import { EventManager } from '../../utils/builder';
import { RanElement } from '../../utils';
/** One file staged for sending. */
export interface Attachment {
    /** Stable for this attachment's life; what `remove` takes and events report. */
    id: string;
    file: File;
    name: string;
    size: number;
    type: string;
    /**
     * Object URL for an image preview, or null for anything else.
     *
     * An object URL, not a data URL: previewing costs a reference to bytes the browser
     * already holds, while reading a 10 MB photo into a base64 string to show a 40px
     * thumbnail costs the string. The data URL is built later, once, by whoever sends.
     */
    previewUrl: string | null;
}
/** Why a file was not accepted. */
export type AttachmentRejection = 'too-large' | 'type-not-accepted' | 'too-many' | 'duplicate';
/**
 * `<r-attachments>` — the files staged alongside a message.
 *
 * It holds the list, previews it, validates what arrives, and owns the object URLs it
 * creates. It does not collect files: paste, drag-and-drop and a file picker are three
 * gestures belonging to three different elements of a composer, and which of them an app
 * offers is the app's decision. Call {@link add} from whichever it wires.
 *
 * ```ts
 * const strip = document.querySelector('r-attachments');
 * input.addEventListener('paste', (e) => {
 *   if (e.clipboardData?.files.length) strip.add(e.clipboardData.files);
 * });
 * strip.addEventListener('attachmentrejected', (e) => toast(explain(e.detail.reason)));
 * ```
 *
 * **Rejection is reported, never silent.** A file that vanishes because it was 3 MB over a
 * limit nobody mentioned reads as a bug in the page.
 *
 * Attributes: `accept` (as `<input accept>`), `max-size` (bytes), `max-count`, `sheet`.
 * `count` is reflected so an empty strip can take no space.
 *
 * Events: `attachmentschange` (`{ attachments }`), `attachmentrejected`
 * (`{ file, reason }`).
 */
export declare class Attachments extends RanElement {
    _events: EventManager;
    _shadowDom: ShadowRoot;
    _list: HTMLElement;
    private _attachments;
    static get observedAttributes(): string[];
    constructor();
    /** The staged files, in the order they arrived. */
    get attachments(): readonly Attachment[];
    /** Just the files, for building a request body. */
    get files(): File[];
    /** Comma-separated types or extensions, in the form `<input accept>` takes. */
    get accept(): string;
    set accept(value: string);
    /** Largest file accepted, in bytes. */
    get maxSize(): number;
    set maxSize(value: number);
    /** Most files that may be staged at once; unlimited when unset. */
    get maxCount(): number;
    set maxCount(value: number);
    get sheet(): string;
    set sheet(value: string);
    /**
     * Stages files, rejecting what does not qualify.
     *
     * @param files Anything iterable of `File` — a `FileList` from a picker, a drop, or a
     *   paste.
     * @returns The attachments that were accepted, in arrival order.
     */
    add(files: Iterable<File>): Attachment[];
    /**
     * Removes one attachment and releases its preview.
     *
     * Named `detach` rather than `remove` because every element already has a `remove()` that
     * takes no arguments and takes itself out of the document. Shadowing it with different
     * semantics is a trap for anyone who reaches for the standard method.
     *
     * @param id The attachment id.
     * @returns Whether anything was removed.
     */
    detach(id: string): boolean;
    /** Removes everything and releases every preview — what sending should call. */
    clear(): void;
    connectedCallback(): void;
    disconnectedCallback(): void;
    attributeChangedCallback(name: string, old: string | null, next: string | null): void;
    handlerExternalCss: () => void;
    private _release;
    private _emit;
    /**
     * Decides whether a file may be staged.
     *
     * @param file The candidate.
     * @returns The reason to refuse it, or null to accept.
     */
    private _reject;
    /**
     * Matches a file against the `accept` list, the way a file picker does.
     *
     * @param file The candidate.
     * @returns Whether its type or extension is listed.
     */
    private _accepts;
    private _render;
}
export default Attachments;
