import{type PropertyValues,type TemplateResult}from'lit';import{LyraElement}from'../../../internal/lyra-element.js';import{type FormOwnerValue}from'../../../internal/form-associated.js';import type{LyraSize}from'../../../internal/variants.js';export type LyraFileInputCapture=''|'user'|'environment'; /** What a `validators` entry may return: nothing/`true` passes, a string is the message, `false` is * a generic failure, and an object of {@linkcode ValidityStateFlags} names the flags to raise. */ export type LyraFileInputValidatorResult=void|boolean|string|ValidityStateFlags; /** Result shape accepted from object validators used by the upstream form-control contract. */ export interface LyraFileInputObjectValidatorResult{message:string;isValid:boolean;invalidKeys:Exclude[];} /** Structural compatibility shape for an object validator. The `never` callback input is * intentional: it lets an array typed by another custom-element package remain assignable while * Lyra invokes the callback with this host at runtime. Author new Lyra validators with the * strongly typed function or `validate()` branches of {@linkcode LyraFileInputValidator}. */ export interface LyraFileInputObjectValidator{ /** Host attributes that trigger a fresh validity check when they change. */ observedAttributes?:string[];checkValidity:(input:never)=>LyraFileInputObjectValidatorResult;message?:string|((input:never)=>string);}export type LyraFileInputValidator=((value:File[],input:LyraFileInput)=>LyraFileInputValidatorResult)|{validate(value:File[],input:LyraFileInput):LyraFileInputValidatorResult;}|LyraFileInputObjectValidator;export declare const DEFAULT_MAX_FILE_SIZE_BYTES:number; /** Fallback used by `effectiveMaxFiles` for an invalid (negative/`NaN`) `maxFiles` override, * mirroring `DEFAULT_MAX_FILE_SIZE_BYTES`'s fail-safe role for `maxFileSize`. */ export declare const DEFAULT_MAX_FILES=100; /** Fallback used by `effectiveMaxTotalSize` for an invalid (negative/`NaN`) `maxTotalSize` * override, mirroring `DEFAULT_MAX_FILE_SIZE_BYTES`'s fail-safe role for `maxFileSize`. */ export declare const DEFAULT_MAX_TOTAL_SIZE_BYTES:number;export interface LyraFileInputRejectedFile{readonly file:File;readonly reason:'type'|'count'|'size'|'directory'|'read'|'limit'|'maxFiles'|'maxTotalSize';}export interface LyraFileInputFilesDetail{readonly files:readonly File[];readonly rejected:readonly LyraFileInputRejectedFile[]; /** Remaining allowance under `maxFiles` after this batch, at the control's running count * (retained files, unless `nonRetaining`, plus `heldFileCount`) -- `null` while `maxFiles` is * unset (no limit), never negative. */ readonly remainingFiles:number|null; /** Remaining allowance under `maxTotalSize` after this batch, in bytes -- `null` while * `maxTotalSize` is unset (no limit), never negative. */ readonly remainingTotalSize:number|null;} /** `lr-files`' event type, narrowing `target`/`currentTarget` to `LyraFileInput` so a listener * reads them without casting. */ export interface LyraFileInputFilesEvent extends CustomEvent{readonly target:LyraFileInput;readonly currentTarget:LyraFileInput;}export interface LyraFileInputEventMap{blur:FocusEvent;focus:FocusEvent;input:Event;change:Event;'lr-invalid':CustomEvent;'lr-files':LyraFileInputFilesEvent;} /** * `` — a drag-drop + click-to-browse file dropzone. Emits * raw `File[]`; parsing (CSV/XLSX/etc.) is left to the host, since that's * where files ultimately get uploaded and processed anyway. * * @customElement lr-file-input * @slot - Custom drop-zone content, overrides the visible `label` text. The * accessible name comes from a host `aria-label` when present, then falls * back to `label`, so icon-only slot content remains announced correctly. * @slot dropzone - Named equivalent of the default dropzone-content slot. * @slot label - Custom form-control label content. * @slot hint - Custom form-control hint content. * @slot error - Custom validation error content. Use `with-error` when this slot is populated in * server-rendered declarative shadow DOM before light-DOM slot assignment is observable. * @event lr-files - Frozen `detail: { files, rejected, remainingFiles, remainingTotalSize }` with * detached readonly sequences and rejected-file records, fired on drop and manual selection. * `remainingFiles`/`remainingTotalSize` report the allowance still left under `maxFiles`/ * `maxTotalSize` after this batch (`null` while that limit is unset). Immutable `File` items * retain identity. Typed as {@linkcode LyraFileInputFilesEvent}, so * `event.target`/`event.currentTarget` are `LyraFileInput` without a cast. Still fires while * `nonRetaining` is set, even though `files` itself is never written in that mode. * @event {Event} input - Native event fired before `change` when user interaction changes `files`; * bubbling, composed, and non-cancelable. * @event {Event} change - Native event fired after `input` when user interaction changes `files`; * bubbling, composed, and non-cancelable. * @event {FocusEvent} focus - Fired when the semantic dropzone receives focus; bubbling, composed, * and non-cancelable. * @event {FocusEvent} blur - Fired when the semantic dropzone loses focus; bubbling, composed, and * non-cancelable. * @event lr-invalid - The file input failed a validity check. Cancelable: calling * `preventDefault()` also cancels the native `invalid` event behind it, suppressing the browser's * own validation bubble so an app can present the failure its own way. * @csspart file-input - The interactive picker surface. * @csspart form-control - The complete label, dropzone, selected-file, error, and hint frame. * @csspart form-control-label - The form-control label. * @csspart label - Deprecated in 8.2.3; compatibility name for `form-control-label`; both names * are on the same node. * @csspart hint - The form-control hint. * @csspart error - The visible validation message or authored error content. * @csspart dropzone - The drag/drop and paste target around the semantic button. * @csspart dropzone-icon - The default decorative file icon. * @csspart dropzone-text - Wrapper around dropzone slot/text content. * @csspart base - Deprecated in 8.2.3; compatibility name for `file-input`; both names are on the * native dropzone button, visually backing the slotted content while remaining its sibling in * the accessibility tree so arbitrary slotted controls are never nested in it. * @csspart input - The visually-hidden native ``. * @csspart status - The visually-hidden, `aria-hidden` mirror of the drag accept/reject state and * accepted/rejected selection counts. The announcement itself lands in the shared light-DOM polite * region (`acquireAnnouncementSink()` in `internal/announcer.ts`) — a live region inside a shadow * root is not reliably announced — so this part is a styling/inspection surface only. * @csspart rejection - The visible region listing each currently-rejected file alongside its * reason, rendered in addition to (never in place of) the sr-only `status` summary. Its text stays * in the accessibility tree as ordinary visible content; the interrupting announcement it used to * make as a shadow `role="alert"` now goes through the shared light-DOM assertive region instead. * @csspart file-list - The current selected-file list. * @csspart file - One selected-file row. * @csspart file-thumbnail - One selected file's thumbnail/icon wrapper. * @csspart file-image - Image preview for an image file. * @csspart file-icon - Generic icon for a non-image file. * @csspart file-details - Filename and formatted-size wrapper. * @csspart file-name - Selected filename. * @csspart file-size - Localized selected-file size. * @csspart remove-button - Removes one selected file. * @cssstate required - Matches while `required` is set. Style with `lr-file-input:state(required)`. * @cssstate optional - Matches while `required` is not set — the complement of `required`. * @cssstate valid - Matches while the control satisfies its constraints — `required`, every entry * in `validators`, and any `setCustomValidity()` error. * @cssstate invalid - Matches while it does not — from the very first render, before the user has * touched anything. Neither this nor `user-invalid` matches while the control is barred from * constraint validation (disabled, or inside a disabled fieldset). * @cssstate user-valid - `valid`, but only after the user has interacted: choosing or dropping * files, removing one, a blur, `reportValidity()`, or a submission attempt. Not after a silent * `checkValidity()` alone. * @cssstate user-invalid - `invalid` after that same interaction. Style validation errors with this * rather than `invalid`: a pristine required file input is genuinely invalid, but colouring it red * before the user has done anything is hostile. * @cssstate blank - Matches while no files are selected -- or, while `nonRetaining` is set, * while `valuePresent` is also unset. * @cssstate dragging - Matches during an active file drag session. * @cssprop [--lr-file-input-font-size=var(--lr-form-control-font-size)] - Label and selected-filename * text size; tracks the shared `size` ladder. * @cssprop [--lr-file-input-dropzone-font-size=var(--lr-font-size-md-sm)] - Instructional text size * inside the dropzone. Retuned per `size` tier; the documented default is the `m`/`medium` tier. * @cssprop [--lr-file-input-dropzone-icon-size=var(--lr-font-size-xl)] - `[part="dropzone-icon"]` * glyph size. Retuned per `size` tier. * @cssprop [--lr-file-input-dropzone-padding=var(--lr-space-l)] - Padding inside `[part~="base"]` * and the stacked dropzone content. Retuned per `size` tier; `compact` overrides it. * @cssprop [--lr-file-input-detail-font-size=var(--lr-font-size-sm)] - Size of the secondary text: * the hint, the validation error, and each selected file's formatted size. Retuned per `size` tier. * @cssprop [--lr-file-input-gap=var(--lr-space-xs)] - Gap between the dropzone's slotted * children. While `compact`, this is the fallback when `--lr-file-input-compact-gap` is unset. * @cssprop [--lr-file-input-radius=var(--lr-radius)] - Corner radius of `[part~="base"]`. * @cssprop [--lr-file-input-compact-padding=var(--lr-space-s)] - `[part~="base"]` padding while * `compact`. * @cssprop [--lr-file-input-compact-gap=var(--lr-space-2xs)] - Gap between the dropzone's slotted * children while `compact`. * @cssprop [--lr-file-input-compact-font-size=var(--lr-font-size-sm)] - Label font size while * `compact`. * @cssprop [--lr-file-input-accept-border-color=var(--lr-color-success)] - Border color of * `[part~="base"][data-drag-state="accept"]`. * @cssprop [--lr-file-input-accept-bg=color-mix(in srgb, var(--lr-color-success) 8%, transparent)] - * Background of `[part~="base"][data-drag-state="accept"]`. * @cssprop [--lr-file-input-reject-border-color=var(--lr-color-danger)] - Border color of * `[part~="base"][data-drag-state="reject"]`. * @cssprop [--lr-file-input-reject-bg=color-mix(in srgb, var(--lr-color-danger) 8%, transparent)] - * Background of `[part~="base"][data-drag-state="reject"]`. * @cssprop [--lr-file-input-dropzone-fill=var(--lr-color-surface)] - Resting dropzone background, * the state it spends most of its life in. The drag accept/reject tints have had their own hooks * since 12.0.0; this one completes the set. * @cssprop [--lr-file-input-dropzone-border-color=var(--lr-color-border)] - Resting dropzone border * color. The dashed border style is unchanged. * @cssprop [--lr-file-input-dropzone-hover-border-color=var(--lr-color-brand)] - Dropzone border * color while the pointer is over it, whether over the button or over the content stacked on it. * @cssprop [--lr-form-control-focus-shadow=none] - The shared field focus halo, painted as a * `box-shadow` while this control is focused. One name for every field-shaped control in the * library, so a halo is configured once rather than per component. Additive: the focus outline and * border cue are the accessibility answer to focus and are never replaced by it. * @cssprop [--lr-form-control-required-content=' *'] - The required marker appended to * `form-control-label` while `required` is set. Set it to `''` to suppress the marker, or to any * other quoted string (`' (required)'`, a localized word) to replace it. * @cssprop [--lr-form-control-required-color=var(--lr-color-danger)] - Required-marker color, * themeable independently of error text and invalid borders. * @cssprop [--lr-form-control-required-offset=0] - Inline space between the label text and the * required marker. * @status stable * @since 4.0.0 */ export declare class LyraFileInput extends LyraElement{protected static readonly immutableEventDetails:readonly string[];static formAssociated:boolean;static styles:import("lit").CSSResultGroup[];static properties:{customError:{attribute:string;reflect:boolean;noAccessor:boolean;};name:{reflect:boolean;noAccessor:boolean;};files:{attribute:boolean;noAccessor:boolean;};disabled:{type:BooleanConstructor;reflect:boolean;noAccessor:boolean;};required:{type:BooleanConstructor;reflect:boolean;noAccessor:boolean;};};multiple:boolean; /** Tighter dropzone padding, gap and label font for constrained spaces (a toolbar, a table cell) * -- same convention as `lr-empty`'s `compact`. Defaults to `false`, i.e. the full `--lr-space-l` * dropzone. The dashed border stays; only the internal spacing shrinks. */ compact:boolean;accept:string; /** Mobile capture hint forwarded to the native file picker. */ capture:LyraFileInputCapture;private _allowedMimeTypes; /** Exact MIME allowlist. Assignment takes a bounded immutable snapshot. */ get allowedMimeTypes():readonly string[];set allowedMimeTypes(next:readonly string[]);private _forbiddenMimeTypes; /** Exact MIME denylist, evaluated before `allowedMimeTypes`. Assignment takes a bounded * immutable snapshot. */ get forbiddenMimeTypes():readonly string[];set forbiddenMimeTypes(next:readonly string[]); /** Largest accepted file size in bytes. `0` (the default) disables the size check entirely -- * see `effectiveMaxFileSize` for how an invalid override is handled. */ maxFileSize:number; /** Largest total number of files accepted, counting retained files (unless `nonRetaining`) plus * `heldFileCount` plus the current batch. `0` (the default) disables the check. Same * rejection-UI shape as `maxFileSize`: an excess file in the batch is rejected with reason * `'maxFiles'` and appears in `[part="rejection"]` alongside any other rejection, rather than * failing the whole selection. An invalid override (negative, `NaN`) falls back to a sane cap * rather than silently accepting an unlimited count -- see `effectiveMaxFiles`. */ maxFiles:number; /** Largest combined byte size accepted, summing retained files (unless `nonRetaining`) plus * `heldTotalSize` plus the current batch. `0` (the default) disables the check. Same * rejection-UI shape and invalid-override fallback as `maxFileSize` -- see * `effectiveMaxTotalSize`. */ maxTotalSize:number; /** Externally held file count added to the running count `maxFiles` evaluates against, in both * retaining and `nonRetaining` modes -- the numeric counterpart of `valuePresent`, for a * cumulative cap that spans separate picker sessions (e.g. a server-backed upload limit) rather * than resetting to what this control alone can see. `0` (the default) means "nothing held" and * reproduces prior behavior exactly. A negative, `NaN`, or `Infinity` value is normalized to `0` * via `finiteCount` -- an invalid baseline degrades to "nothing held" rather than corrupting * every later comparison or permanently blocking every future file. */ heldFileCount:number; /** Externally held byte total added to the running size `maxTotalSize` evaluates against, in * both retaining and `nonRetaining` modes. Same contract, default, and invalid-input * normalization as `heldFileCount`. */ heldTotalSize:number; /** Opt-in mode where an accepted selection still fires `lr-files`/`input`/`change` but is never * written to `files` or rendered as a built-in `[part="file"]` row -- for a host that persists * files elsewhere and renders its own list, so assigning `files` (even to reset it) never fights * that host-owned rendering. `required` validity and the `blank` state read `valuePresent` * instead of `files.length` while this is set. Does not affect `formStateRestoreCallback()` or a * direct `files` assignment, both of which still retain. */ nonRetaining:boolean; /** External "a value is present" signal for a `nonRetaining` host to set once it has taken * ownership of the selected files, so `required` validity and the `blank` state reflect * externally-held files instead of the always-empty internal list. Ignored while `nonRetaining` * is `false`. */ valuePresent:boolean; /** Enables directory selection through the browser's native picker. */ directory:boolean; /** Enables files pasted from the clipboard into the dropzone. `true`-defaulting, so a plain * `paste="false"` attribute (not just a `.paste=${false}` property binding) actually disables it. */ paste:boolean; /** Form-control label. Empty or removed leaves the localized dropzone instruction as the visible fallback. */ label:string; /** Optional hint copy. Removing the attribute removes its text and description association. */ hint:string; /** Plain-text validation error. A custom-validity message is shown when this is empty. */ errorText:string; /** SSR slot-presence hint for label content. */ withLabel:boolean; /** SSR slot-presence hint for hint content. */ withHint:boolean; /** SSR slot-presence hint for rich error content. */ withError:boolean;size:LyraSize; /** Additional JavaScript validators run after the intrinsic `required` constraint — the same * contract `lr-date-input` and `lr-combobox` implement. Accepts a function, an object with * `validate(value, input)`, or the mapped object-validator shape with `checkValidity(input)` and * `{ isValid, message, invalidKeys }` results. The value handed to a function/`validate()` * validator is the current `files` array. Object validators can list host `observedAttributes` * that should trigger live revalidation. A validator that throws fails closed with the generic * localized message. Barred (own or fieldset-cascaded `disabled`) exactly like the intrinsic * constraint. */ validators:LyraFileInputValidator[]; /** Accessible name forwarded to the semantic dropzone and native file input. * When unset, the effective `label` text is used. */ accessibleLabel:string; /** Message announced after an accepted selection; `{count}` is replaced by the number of * accepted files. `undefined` uses the localized singular/plural default; every supplied * string, including `''` and the former English default, is caller-owned. */ acceptedMessage?:string; /** Message announced after rejected files; `{count}` is replaced by the number of rejected * files. `undefined` uses the localized singular/plural default; every supplied string, * including `''` and the former English default, is caller-owned. */ rejectedMessage?:string;private dragState;private resultStatus; /** Files rejected by the most recent drop/paste/selection, each paired with its reason. * Populated in `emitFiles()` (never on mount -- it starts empty and every write is a direct * consequence of a user action), so the visible `[part="rejection"]` alert naturally never * fires on connect and needs no `isMounting` guard. Cleared back to `[]` whenever a * subsequent classification rejects nothing. */ private rejectedFiles;private touched; /** Bumped whenever an out-of-band revalidation (a validator's `observedAttributes` firing) * changes published validity, so the rendered `[part="error"]` text refreshes without any * reactive property of this host having changed. */ private validityRevision;private readonly slotPresence;private baseEl?;private inputEl?;private internals;private validityController; /** Consumer-supplied validation message reflected through `custom-error`. */ customError:string|null; /** Owns the drag-session state machine and folder traversal -- shared with `lr-drop-zone`. */ private readonly dropSession; /** Shared light-DOM live regions this element announces through. A region rendered inside this * shadow root is not reliably announced (JAWS with Firefox ignores one outright), so * `[part="status"]` is only an `aria-hidden` mirror and `[part="rejection"]` is plain visible * text. */ private politeSink?;private assertiveSink?;private hasSyncedDescribedByElements; /** False until the first render has committed, so mounting never announces a resting state. */ private announcementsArmed;private _name;private _files;private _fileCount;private _disabled;private _required;private validationTargetOverride?;private validatorAttributeObserver?;private _fieldsetDisabled;private thumbnailUrls;constructor();get form():HTMLFormElement|null;set form(owner:FormOwnerValue);getForm():HTMLFormElement|null;get labels():NodeList;get validity():ValidityState;get validationMessage():string;get willValidate():boolean; /** Submitted field name. * @default null */ get name():string|null;set name(next:string|null); /** Selected files. Programmatic writes are silent but immediately synchronize rendering/forms. * @default [] */ get files():File[];set files(next:readonly File[]); /** Readonly selected-file count derived from `files`. * @default 0 */ get fileCount():number; /** Readonly state derived from the current drag session. * @default false */ get dragging():boolean;private get effectiveMultiple(); /** Disables every interactive sub-control. * @default false */ get disabled():boolean;set disabled(next:boolean); /** Requires at least one selected file. * @default false */ get required():boolean;set required(next:boolean);get effectiveDisabled():boolean; /** Constraint-validation popup anchor. The focusable base of the dropzone control is the * default after first render; assign another shadow descendant to override the anchor, or * `undefined` to restore the default. */ get validationTarget():HTMLElement|undefined;set validationTarget(next:HTMLElement|undefined);protected willUpdate(changed:PropertyValues):void;connectedCallback():void;disconnectedCallback():void;protected updated(changed:PropertyValues):void;private syncFormValue;private createFormData;private createRestorationFormData; /** * Shared with every other form control: own `disabled` and a `
` ancestor bar * constraint validation (this control has no `readonly` of its own — a file picker with nothing * to pick from is spelled `disabled`). A barred control matches neither `:valid` nor `:invalid` * natively, so leaving `valueMissing` raised on a disabled required dropzone is what painted it * red under the documented `:state(user-invalid)` rule. */ private get barredFromValidation(); /** Runs `validators` in order and returns the first failure. Mirrors `lr-date-input`'s and * `lr-combobox`'s reading of the same contract: a thrown validator fails closed with the * generic localized message rather than escaping into the caller that happened to write * `files`. */ private validatorResult; /** Watches the host attributes any object validator listed in `observedAttributes`, so changing * one revalidates live. Bound to the owning window so a re-parent into another document (or a * disconnect) can never leave the previous document's observer firing into this host. */ private syncValidatorAttributeObserver;private disconnectValidatorAttributeObserver;private updateValidity; /** Whether the control has a value for `required`/`blank` purposes: real retained files, or -- * while `nonRetaining` is set -- the host's own `valuePresent` signal. */ private get hasEffectiveValue();private publishCustomStates;private markInteracted;checkValidity():boolean;reportValidity():boolean;setCustomValidity(message:string):void;resetValidity():void;formResetCallback():void;formStateRestoreCallback(state:string|File|FormData|null,reason:'autocomplete'|'restore'):void;private readFormDataFiles;formDisabledCallback(disabled:boolean):void;private syncThumbnailUrls; /** `maxFileSize` normalized: `0` (explicitly set, or left at the default) or `Infinity` * (explicitly set) both mean "no limit" verbatim -- `null` here signals that. Anything else * that isn't a positive, finite override -- a `NaN` from an invalid `max-file-size` attribute, * or a negative value -- falls back to a sane cap instead. This matters because the size check * below used to gate directly on `this.maxFileSize > 0`: `NaN > 0` and `-1 > 0` are both * `false`, so an invalid override silently disabled the entire size limit (accepting files of * any size) rather than failing safe. */ private get effectiveMaxFileSize(); /** `maxFiles` normalized exactly like `effectiveMaxFileSize` normalizes `maxFileSize`: `0`/ * `Infinity` both mean "no limit" (`null`); any other invalid override falls back to * `DEFAULT_MAX_FILES` rather than silently disabling the check. */ private get effectiveMaxFiles(); /** `maxTotalSize` normalized exactly like `effectiveMaxFileSize` normalizes `maxFileSize`. */ private get effectiveMaxTotalSize();private isAllowed; /** Sum of `.size` across `files`, tolerating a hostile/undefined getter (a synthetic dragenter- * preview item has none) by treating anything non-finite as `0`. */ private totalFileSize;private classify; /** Per-reason, per-file message for the visible `[part="rejection"]` alert. The filename is * caller-supplied data interpolated via the `values` argument, never localized itself -- * only the surrounding copy comes from `this.localize()`. `'directory'` deliberately reuses * `fileInputFolderRejected` verbatim (its template has no `{filename}` placeholder, so the * extra interpolation value is simply unused). Read and traversal-limit failures have their * own truthful terminal-outcome messages. */ private rejectionMessage;private outcomeMessage;private emitFiles; /** Reads both component state and the UA's synchronous fieldset cascade before public actions. */ private get liveDisabled(); /** Programmatically open the native file picker. */ openPicker():void; /** Focuses the semantic dropzone unless the form control is effectively disabled. */ focus(options?:FocusOptions):void; /** Removes focus from the semantic dropzone. */ blur():void; /** Opens the native picker, matching a user click on the semantic dropzone. */ click():void;private onDragEnter;private onDragOver;private onDragLeave;private onDrop;private folderFailure;private onPaste;private onInputChange;private onFocus;private onBlur;private onKeyDown;private onDropzoneClick;private onVisibleLabelClick;private statusText;private dragStatusText; /** Resolves `label`'s effective text: an explicit override wins verbatim; left at the * built-in default it instead routes through `this.localize()` so a locale/`.strings` * override applies without requiring `label` itself to be set. */ private get effectiveLabel();private removeFile;private fileSize;private renderFile;render():TemplateResult;}declare global{interface HTMLElementTagNameMap{'lr-file-input':LyraFileInput;}}