/** The filter every intake path applies to what arrived. */ export interface FileIntakeFilter { /** Native `accept` filter (e.g. `"application/pdf,image/*"`) — matched against * the file's MIME type (falling back to what its extension says when the file * declares none), or against its filename for a `.ext` pattern. */ accept?: string; /** Keep more than one file. Default true. */ multiple?: boolean; } /** * The structural shape a `DataTransfer` satisfies — `DragEvent.dataTransfer` * (a drop) and `ClipboardEvent.clipboardData` (a paste) are the same object. * Declared structurally so the extractor is testable without a DOM. */ export interface FileTransferLike { readonly files?: ArrayLike | null; readonly items?: ArrayLike<{ readonly kind: string; getAsFile: () => File | null; }> | null; } /** The minimal ref shape `usePasteFiles`/`FileDropTarget` need to locate a * region: anything whose `.current` is the region's DOM node. Declared * structurally (readonly, so a `RefObject` assigns * cleanly) rather than as a specific ref type. */ export interface RegionRef { readonly current: unknown; } /** Options for the paste sink behind ``. */ export interface UsePasteFilesOptions extends FileIntakeFilter { /** Receives the pasted files. Bytes/upload belong to the host. */ onFiles: (files: File[]) => void; /** Subscribe only while true (default true) — scope the sink to "while this * surface is open" so a background screen never swallows a paste. */ enabled?: boolean; /** The region this sink belongs to. When the paste happens while focus is * INSIDE this region, this sink wins over a later-mounted one (see * `selectPasteSink`). Omit for a region-less surface (a modal dialog) — the * sink then participates by stack order alone. */ region?: RegionRef; } /** * Does a file pass a native `accept` list? Each comma-separated pattern is an * extension (`.pdf`), a wildcard type (`image/*`) or an exact MIME * (`application/pdf`); an empty/absent list accepts everything. * * A file whose declared type says NOTHING is judged by its extension instead. * The OS clipboard is the case that forces this: copy a file in * Finder/Explorer and paste it, and the browser hands over real bytes and a * real filename while declaring `""` — or, just as often, * `application/octet-stream`, the same non-answer wearing the shape of one. * Reading either as a MIME mismatch asserts "this is not a PDF" from data that * never said so, and the file is dropped; because a paste carrying nothing * acceptable is deliberately left alone, that drop is invisible. * * `resolveMimeType` owns which declarations count as uninformative, so this * matches on the same type the SERVER will store for the file. */ export declare function matchesAccept(file: File, accept: string | undefined): boolean; /** * The files a drop or a paste carries, filtered by `accept` and capped by * `multiple`. Returns a new array; never throws on a missing/empty transfer. */ export declare function filesFromTransfer(transfer: FileTransferLike | null | undefined, filter?: FileIntakeFilter): File[]; /** One registered paste sink for the routing decision: the payload to hand the * paste to, and whether its region currently contains focus. */ export interface PasteSinkEntry { sink: T; /** True when `document.activeElement` is inside this sink's region. A * region-less sink (a modal dialog) is always false — it routes by stack * order alone. */ focused: boolean; } /** * Which sink gets the paste, given the active sinks in MOUNT order (oldest * first, top of the stack last). The rule: the TOP-MOST focused region wins — * so when two file targets are enabled on the same layer, the one the user is * actually working in takes the file. With NO region focused it falls back to * the top of the stack (the last-mounted surface), which is the right default * for modal stacking (a dialog over a screen). Returns `undefined` for an empty * stack. * * Pure so the DOM-free routing rule is unit-tested here; the `focused` flags are * computed against live focus in the `.web` sink at dispatch time. */ export declare function selectPasteSink(entries: readonly PasteSinkEntry[]): T | undefined;