ng-hub-ui-forms 22.35.1 → 22.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -975,6 +975,14 @@ The datepicker, inputs and validation layer are original to `ng-hub-ui-forms`.
|
|
|
975
975
|
|
|
976
976
|
---
|
|
977
977
|
|
|
978
|
+
## 💼 Commercial support
|
|
979
|
+
|
|
980
|
+
These libraries are maintained by [Carlos Morcillo Fernández](https://www.carlosmorcillo.com), a freelance frontend architect working with teams that build and maintain Angular applications.
|
|
981
|
+
|
|
982
|
+
If your team depends on Hub-UI and needs more than an issue thread can solve, that is my day job: architecture audits, design systems, Angular migrations and team mentoring. For projects that also need design and a full team, I run them through [Frog Hub](https://froghub.es), my development studio.
|
|
983
|
+
|
|
984
|
+
Have a look at [the services](https://www.carlosmorcillo.com/en/services/) or [tell me about your project](https://www.carlosmorcillo.com/en/contact/).
|
|
985
|
+
|
|
978
986
|
## 📄 License
|
|
979
987
|
|
|
980
|
-
MIT © [Carlos Morcillo](https://www.carlosmorcillo.com)
|
|
988
|
+
MIT © [Carlos Morcillo Fernández](https://www.carlosmorcillo.com)
|
|
@@ -11007,7 +11007,7 @@ class HubFileInputComponent extends HubFieldControl {
|
|
|
11007
11007
|
this.announcement.set(this.announcement() === message ? `${message}\u200b` : message);
|
|
11008
11008
|
}
|
|
11009
11009
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFileInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
11010
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFileInputComponent, isStandalone: true, selector: "hub-file-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxTotalSize: { classPropertyName: "maxTotalSize", publicName: "maxTotalSize", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, dragDrop: { classPropertyName: "dragDrop", publicName: "dragDrop", isSignal: true, isRequired: false, transformFunction: null }, paste: { classPropertyName: "paste", publicName: "paste", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, currentFile: { classPropertyName: "currentFile", publicName: "currentFile", isSignal: true, isRequired: false, transformFunction: null }, imagePreview: { classPropertyName: "imagePreview", publicName: "imagePreview", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, capture: { classPropertyName: "capture", publicName: "capture", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, dropText: { classPropertyName: "dropText", publicName: "dropText", isSignal: true, isRequired: false, transformFunction: null }, dropSubtext: { classPropertyName: "dropSubtext", publicName: "dropSubtext", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", rejected: "rejected", fileRemoved: "fileRemoved", currentFileRemoved: "currentFileRemoved", uploadStateChange: "uploadStateChange" }, host: { listeners: { "paste": "handlePaste($event)" }, properties: { "class": "classlist()", "class.hub-file-input-host": "true" } }, queries: [{ propertyName: "iconTpt", first: true, predicate: HubFileIconDirective, descendants: true, isSignal: true }, { propertyName: "previewTpt", first: true, predicate: HubFilePreviewDirective, descendants: true, isSignal: true }, { propertyName: "noticeTpt", first: true, predicate: HubFileDropzoneNoticeDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }, { propertyName: "viewer", first: true, predicate: ["viewer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
11010
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: HubFileInputComponent, isStandalone: true, selector: "hub-file-input", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, labelType: { classPropertyName: "labelType", publicName: "labelType", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxSize: { classPropertyName: "maxSize", publicName: "maxSize", isSignal: true, isRequired: false, transformFunction: null }, minSize: { classPropertyName: "minSize", publicName: "minSize", isSignal: true, isRequired: false, transformFunction: null }, maxTotalSize: { classPropertyName: "maxTotalSize", publicName: "maxTotalSize", isSignal: true, isRequired: false, transformFunction: null }, maxFiles: { classPropertyName: "maxFiles", publicName: "maxFiles", isSignal: true, isRequired: false, transformFunction: null }, dragDrop: { classPropertyName: "dragDrop", publicName: "dragDrop", isSignal: true, isRequired: false, transformFunction: null }, paste: { classPropertyName: "paste", publicName: "paste", isSignal: true, isRequired: false, transformFunction: null }, preview: { classPropertyName: "preview", publicName: "preview", isSignal: true, isRequired: false, transformFunction: null }, currentFile: { classPropertyName: "currentFile", publicName: "currentFile", isSignal: true, isRequired: false, transformFunction: null }, imagePreview: { classPropertyName: "imagePreview", publicName: "imagePreview", isSignal: true, isRequired: false, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, allowDuplicates: { classPropertyName: "allowDuplicates", publicName: "allowDuplicates", isSignal: true, isRequired: false, transformFunction: null }, capture: { classPropertyName: "capture", publicName: "capture", isSignal: true, isRequired: false, transformFunction: null }, autoUpload: { classPropertyName: "autoUpload", publicName: "autoUpload", isSignal: true, isRequired: false, transformFunction: null }, buttonLabel: { classPropertyName: "buttonLabel", publicName: "buttonLabel", isSignal: true, isRequired: false, transformFunction: null }, dropText: { classPropertyName: "dropText", publicName: "dropText", isSignal: true, isRequired: false, transformFunction: null }, dropSubtext: { classPropertyName: "dropSubtext", publicName: "dropSubtext", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, classlist: { classPropertyName: "classlist", publicName: "classlist", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { valueChange: "valueChange", rejected: "rejected", fileRemoved: "fileRemoved", currentFileRemoved: "currentFileRemoved", uploadStateChange: "uploadStateChange" }, host: { listeners: { "paste": "handlePaste($event)" }, properties: { "class": "classlist()", "class.hub-file-input-host": "true" } }, queries: [{ propertyName: "iconTpt", first: true, predicate: HubFileIconDirective, descendants: true, isSignal: true }, { propertyName: "previewTpt", first: true, predicate: HubFilePreviewDirective, descendants: true, isSignal: true }, { propertyName: "noticeTpt", first: true, predicate: HubFileDropzoneNoticeDirective, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "nativeInput", first: true, predicate: ["nativeInput"], descendants: true, isSignal: true }, { propertyName: "viewer", first: true, predicate: ["viewer"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\t\tA nested @if rather than `@else if (iconTpt(); as icon)`: an `as` on an\n\t\t\t\t\t\t\t\t\t\t@else if is only accepted from Angular 20.2, and this package supports\n\t\t\t\t\t\t\t\t\t\tolder ones.\n\t\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t\t@if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: HubTooltipDirective, selector: "[hubTooltip]", inputs: ["hubTooltip", "hubTooltipPlacement", "hubTooltipDelay", "hubTooltipOffset"] }, { kind: "pipe", type: KeyValuePipe, name: "keyvalue" }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
11011
11011
|
}
|
|
11012
11012
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: HubFileInputComponent, decorators: [{
|
|
11013
11013
|
type: Component,
|
|
@@ -11015,7 +11015,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
11015
11015
|
'[class]': 'classlist()',
|
|
11016
11016
|
'[class.hub-file-input-host]': 'true',
|
|
11017
11017
|
'(paste)': 'handlePaste($event)'
|
|
11018
|
-
}, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"] }]
|
|
11018
|
+
}, template: "<div\n\tclass=\"hub-field hub-file-input\"\n\t[class.hub-field--disabled]=\"disabled()\"\n\t[class.hub-field--invalid]=\"isInvalid\"\n\t[class.hub-field--valid]=\"showsValid\"\n>\n\t@if (showsFormTextTooltip()) {\n\t\t<!--\n\t\t\tThe row exists because the hint does, not because the label does. A field with a\n\t\t\tfloating label \u2014 or no label at all \u2014 still has helper text to offer, and the mark\n\t\t\tis the only place left to offer it from once the block below stands down.\n\t\t-->\n\t\t<div class=\"hub-field__label-row\">\n\t\t\t@if (label() || required()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t\t\t}\n\t\t\t<button\n\t\t\t\ttype=\"button\"\n\t\t\t\tclass=\"hub-field__hint\"\n\t\t\t\t[attr.aria-label]=\"formText()\"\n\t\t\t\t[hubTooltip]=\"formText()\"\n\t\t\t\thubTooltipPlacement=\"top\"\n\t\t\t></button>\n\t\t</div>\n\t} @else if (label() || required()) {\n\t\t<ng-container [ngTemplateOutlet]=\"hubFieldLabelTpl\" />\n\t}\n\n\t<ng-template #hubFieldLabelTpl>\n\t\t<label\n\t\t\t[for]=\"id\"\n\t\t\tclass=\"hub-field__label\"\n\t\t\t[class.hub-field__label--visually-hidden]=\"labelType() === _labelTypes.VisuallyHidden\"\n\t\t>\n\t\t\t{{ label() }}\n\t\t\t@if (required()) {\n\t\t\t\t<span class=\"hub-field__required\" aria-hidden=\"true\">*</span>\n\t\t\t}\n\t\t</label>\n\t</ng-template>\n\n\t<div\n\t\tclass=\"hub-field__body\"\n\t\t[class.hub-file-input__body--inline]=\"_inlineSingle()\"\n\t\t[class.hub-file-input__body--inline-multiple]=\"_inlineMultiple()\"\n\t>\n\t\t<!-- The frame listens for the drag, so a drop lands anywhere on the field, tiles included. -->\n\t\t<div\n\t\t\tclass=\"hub-file-input__frame\"\n\t\t\t[class.hub-file-input__frame--dragover]=\"isDragging()\"\n\t\t\t(dragenter)=\"handleDragEnter($event)\"\n\t\t\t(dragover)=\"handleDragOver($event)\"\n\t\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t\t(drop)=\"handleDrop($event)\"\n\t\t>\n\t\t\t@if (_dropzone() === 'zone') {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: false }\" />\n\t\t\t}\n\n\t\t\t@if (_tiles().length > 0) {\n\t\t\t\t<ul class=\"hub-file-input__tiles\" [class.hub-file-input__tiles--single]=\"_inlineSingle()\">\n\t\t\t\t\t@for (tile of _tiles(); track tile.key; let index = $index) {\n\t\t\t\t\t\t<li\n\t\t\t\t\t\t\tclass=\"hub-file-input__tile\"\n\t\t\t\t\t\t\t[class.hub-file-input__tile--changeable]=\"_canChange() && tile.item?.status !== 'uploading'\"\n\t\t\t\t\t\t\t[attr.data-file-kind]=\"tile.kind\"\n\t\t\t\t\t\t\t[attr.data-status]=\"tile.item?.status ?? null\"\n\t\t\t\t\t\t\t[attr.title]=\"tile.name\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\tActivating a tile opens its file: a stored one is a link to its URL, in a new tab;\n\t\t\t\t\t\t\t\ta picked image opens enlarged; any other picked file opens in a new tab. Replacing\n\t\t\t\t\t\t\t\thas its own button, the pill, so one gesture never means two things.\n\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t@if (tile.current) {\n\t\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[href]=\"tile.current.url\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-open\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().open(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"openTile(tile, $event)\"\n\t\t\t\t\t\t\t\t\t(keydown)=\"handleTileKeydown($event, tile, index)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tileBodyTpl\"\n\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: tile }\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (_canChange() && tile.item?.status !== 'uploading') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-veil\" aria-hidden=\"true\"></span>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__tile-replace\"\n\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().replaceFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t(click)=\"replaceTile(tile)\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{{ labels().replace }}\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress hub-file-input__tile-progress\"\n\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"tile.item?.progress === null\"\n\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"tile.item?.progress\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"tile.item?.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-error\">{{ errorText(tile.item!) }}</span>\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__tile-actions\">\n\t\t\t\t\t\t\t\t@if (tile.item?.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t@if (hasUploader) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--cancel\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t@if (tile.item?.status === 'error') {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--retry\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"retry(tile.item!.id)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t@if (_canRemove()) {\n\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--remove\"\n\t\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().removeFile(tile.name)\"\n\t\t\t\t\t\t\t\t\t\t\t(click)=\"removeTile(tile, index)\"\n\t\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (_dropzone() === 'add') {\n\t\t\t\t\t\t<li class=\"hub-file-input__tile hub-file-input__tile--add\">\n\t\t\t\t\t\t\t<ng-container [ngTemplateOutlet]=\"dropzoneTpl\" [ngTemplateOutletContext]=\"{ $implicit: true }\" />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t}\n\t\t\t\t</ul>\n\t\t\t}\n\n\t\t\t@if (_isInline()) {\n\t\t\t\t<!--\n\t\t\t\t\tInline keeps the native input out of the label, after the tiles: it is never re-created\n\t\t\t\t\twhen the field fills or empties, focus can always return to it, and its place in the tab\n\t\t\t\t\torder is the add tile's.\n\t\t\t\t-->\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t\t}\n\n\t\t\t@if (_showCount()) {\n\t\t\t\t<p class=\"hub-file-input__count\" [id]=\"id + '-count'\">{{ labels().count(_heldCount(), maxFiles()!) }}</p>\n\t\t\t}\n\t\t</div>\n\n\t\t@if (_listPreview() && _items().length > 0) {\n\t\t\t<ul class=\"hub-file-input__list\" [class.hub-file-input__list--grid]=\"_listPreview() === 'grid'\">\n\t\t\t\t@for (item of _items(); track item.id) {\n\t\t\t\t\t<li class=\"hub-file-input__item\" [attr.data-status]=\"item.status\">\n\t\t\t\t\t\t@if (previewTpt(); as tpt) {\n\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"tpt.template\"\n\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"previewContext(item)\"\n\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t<span class=\"hub-file-input__thumb\" aria-hidden=\"true\">\n\t\t\t\t\t\t\t\t@if (item.previewUrl) {\n\t\t\t\t\t\t\t\t\t<img class=\"hub-file-input__image\" [src]=\"item.previewUrl\" alt=\"\" />\n\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t<!--\n\t\t\t\t\t\t\t\t\t\tA nested @if rather than `@else if (iconTpt(); as icon)`: an `as` on an\n\t\t\t\t\t\t\t\t\t\t@else if is only accepted from Angular 20.2, and this package supports\n\t\t\t\t\t\t\t\t\t\tolder ones.\n\t\t\t\t\t\t\t\t\t-->\n\t\t\t\t\t\t\t\t\t@if (iconTpt(); as icon) {\n\t\t\t\t\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t\t\t\t\t[ngTemplateOutlet]=\"icon.template\"\n\t\t\t\t\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: item }\"\n\t\t\t\t\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t\t\t\t} @else {\n\t\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__file-icon\"></span>\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__meta\">\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__name\" [title]=\"item.file.name\">{{ item.file.name }}</span>\n\t\t\t\t\t\t\t\t<span class=\"hub-file-input__size\">{{ labels().formatSize(item.file.size) }}</span>\n\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress\"\n\t\t\t\t\t\t\t\t\t\t[class.hub-file-input__progress--indeterminate]=\"item.progress === null\"\n\t\t\t\t\t\t\t\t\t\trole=\"progressbar\"\n\t\t\t\t\t\t\t\t\t\taria-valuemin=\"0\"\n\t\t\t\t\t\t\t\t\t\taria-valuemax=\"100\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-valuenow]=\"item.progress\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__progress-bar\"\n\t\t\t\t\t\t\t\t\t\t\t[style.--hub-file-input-progress-value]=\"item.progress ?? 0\"\n\t\t\t\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<span class=\"hub-file-input__error\">{{ errorText(item) }}</span>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\n\t\t\t\t\t\t\t<span class=\"hub-file-input__actions\">\n\t\t\t\t\t\t\t\t@if (item.status === 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--cancel\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().cancel\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"cancel(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (item.status === 'error') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--retry\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().retry\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"retry(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t@if (_canRemove() && item.status !== 'uploading') {\n\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\tclass=\"hub-file-input__action hub-file-input__action--remove\"\n\t\t\t\t\t\t\t\t\t\t[attr.aria-label]=\"labels().remove\"\n\t\t\t\t\t\t\t\t\t\t(click)=\"remove(item.id)\"\n\t\t\t\t\t\t\t\t\t></button>\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t}\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\n\t\t\t@if (_items().length > 1 && _canRemove()) {\n\t\t\t\t<button type=\"button\" class=\"hub-file-input__clear\" (click)=\"clear()\">{{ labels().clear }}</button>\n\t\t\t}\n\t\t}\n\t</div>\n\n\t@if (!showsFormTextTooltip() && (formText() || formTextTmp())) {\n\t\t<div class=\"hub-field__form-text\" [class.hub-field__form-text--disabled]=\"disabled()\">\n\t\t\t@if (formTextTmp()) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"formTextTmp()!\"></ng-container>\n\t\t\t} @else {\n\t\t\t\t{{ formText() }}\n\t\t\t}\n\t\t</div>\n\t}\n\n\t@if (isInvalid) {\n\t\t<div class=\"hub-field__feedback\" role=\"alert\">\n\t\t\t<ul>\n\t\t\t\t@for (error of errors | keyvalue; track error.key) {\n\t\t\t\t\t<li>\n\t\t\t\t\t\t<ng-container\n\t\t\t\t\t\t\t[ngTemplateOutlet]=\"_errorTemplates[error.key] ?? defaultErrorTpt\"\n\t\t\t\t\t\t\t[ngTemplateOutletContext]=\"{ $implicit: error.value, value: error.value }\"\n\t\t\t\t\t\t></ng-container>\n\t\t\t\t\t\t<ng-template #defaultErrorTpt>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tclass=\"hub-field__feedback-text\"\n\t\t\t\t\t\t\t\t[innerHTML]=\"getInvalidFeedbackTemplate(error.key, error.value)\"\n\t\t\t\t\t\t\t></span>\n\t\t\t\t\t\t</ng-template>\n\t\t\t\t\t</li>\n\t\t\t\t}\n\t\t\t</ul>\n\t\t</div>\n\t}\n\n\t@if (showsValid && validFeedback()) {\n\t\t<div class=\"hub-field__feedback hub-field__feedback--valid\" role=\"status\">\n\t\t\t<span class=\"hub-field__feedback-text\">{{ validFeedback() }}</span>\n\t\t</div>\n\t}\n\n\t<span class=\"hub-file-input__live\" aria-live=\"polite\">{{ announcement() }}</span>\n\n\t<!--\n\t\tThe enlarged image. A native modal <dialog> does the hard parts: Escape closes it, the page\n\t\tbehind turns inert so focus stays inside, and it sits in the top layer above any stacking\n\t\tcontext. Focus goes back to the tile on close, whichever way it closes.\n\t-->\n\t<dialog\n\t\t#viewer\n\t\tclass=\"hub-file-input__viewer\"\n\t\t[attr.aria-label]=\"_viewing()?.name ?? null\"\n\t\t(close)=\"handleViewerClose()\"\n\t\t(click)=\"handleViewerClick($event)\"\n\t>\n\t\t@if (_viewing(); as viewing) {\n\t\t\t<figure class=\"hub-file-input__viewer-figure\">\n\t\t\t\t<img class=\"hub-file-input__viewer-image\" [src]=\"viewing.src\" [alt]=\"viewing.name\" />\n\t\t\t\t<figcaption class=\"hub-file-input__viewer-caption\">{{ viewing.name }}</figcaption>\n\t\t\t</figure>\n\t\t}\n\t\t<button\n\t\t\ttype=\"button\"\n\t\t\tclass=\"hub-file-input__chip hub-file-input__chip--close\"\n\t\t\t[attr.aria-label]=\"labels().close\"\n\t\t\t(click)=\"closeViewer()\"\n\t\t\tautofocus\n\t\t></button>\n\t</dialog>\n</div>\n\n<!--\n\tThe dropzone is a <label> bound to the hidden native input: clicking or activating it with the\n\tkeyboard opens the file dialog through the platform, so no role, tabindex or key handler is\n\tneeded. The \"browse\" affordance is a <span>, not a <button>, because a button inside a label would\n\topen the dialog twice. As the add tile it keeps only the glyph and the browse text.\n-->\n<ng-template #dropzoneTpl let-add>\n\t<label\n\t\tclass=\"hub-file-input__dropzone\"\n\t\t[for]=\"id\"\n\t\t[class.hub-file-input__dropzone--add]=\"add\"\n\t\t[class.hub-file-input__dropzone--dragover]=\"isDragging()\"\n\t\t[class.hub-file-input__dropzone--no-drop]=\"!dragDrop()\"\n\t\t[class.hub-file-input__dropzone--invalid]=\"isInvalid\"\n\t\t[class.hub-file-input__dropzone--readonly]=\"readonly()\"\n\t>\n\t\t@if (!_isInline()) {\n\t\t\t<ng-container [ngTemplateOutlet]=\"nativeTpl\" />\n\t\t}\n\n\t\t<span class=\"hub-file-input__icon\" aria-hidden=\"true\"></span>\n\n\t\t@if (add) {\n\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t} @else {\n\t\t\t@if (noticeTpt(); as notice) {\n\t\t\t\t<ng-container [ngTemplateOutlet]=\"notice.template\"></ng-container>\n\t\t\t}\n\n\t\t\t<span class=\"hub-file-input__prompt\">\n\t\t\t\t@if (dragDrop()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-text\">{{ dropTextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t@if (dropSubtextLabel()) {\n\t\t\t\t\t<span class=\"hub-file-input__drop-subtext\">{{ dropSubtextLabel() }}</span>\n\t\t\t\t}\n\t\t\t\t<span class=\"hub-file-input__browse\">{{ browseLabel() }}</span>\n\t\t\t</span>\n\t\t}\n\n\t\t@if (constraintsHint()) {\n\t\t\t<span class=\"hub-file-input__hint\" [class.hub-file-input__hint--hidden]=\"add\" [id]=\"id + '-hint'\">{{\n\t\t\t\tconstraintsHint()\n\t\t\t}}</span>\n\t\t}\n\t</label>\n</ng-template>\n\n<ng-template #nativeTpl>\n\t<input\n\t\t#nativeInput\n\t\ttype=\"file\"\n\t\tclass=\"hub-file-input__native\"\n\t\t[id]=\"id\"\n\t\t[accept]=\"accept()\"\n\t\t[multiple]=\"multiple()\"\n\t\t[disabled]=\"disabled()\"\n\t\t[attr.capture]=\"capture()\"\n\t\t[attr.tabindex]=\"_dropzone() === 'none' ? -1 : null\"\n\t\t[attr.aria-required]=\"required() ? 'true' : null\"\n\t\t[attr.aria-invalid]=\"isInvalid\"\n\t\t[attr.aria-describedby]=\"_describedBy()\"\n\t\t(click)=\"guardNativeClick($event)\"\n\t\t(cancel)=\"cancelReplace()\"\n\t\t(change)=\"handleNativeChange($event)\"\n\t\t(blur)=\"handleBlur($event)\"\n\t/>\n</ng-template>\n\n<ng-template #tileBodyTpl let-tile>\n\t@if (tile.src) {\n\t\t<img class=\"hub-file-input__tile-image\" [src]=\"tile.src\" alt=\"\" (error)=\"markBroken(tile.src)\" />\n\t} @else {\n\t\t<span class=\"hub-file-input__tile-file\">\n\t\t\t<span class=\"hub-file-input__kind-icon\" aria-hidden=\"true\"></span>\n\t\t\t<span class=\"hub-file-input__tile-name\">\n\t\t\t\t<span class=\"hub-file-input__tile-stem\">{{ tile.stem }}</span>\n\t\t\t\t@if (tile.ext) {\n\t\t\t\t\t<span class=\"hub-file-input__tile-ext\">{{ tile.ext }}</span>\n\t\t\t\t}\n\t\t\t</span>\n\t\t</span>\n\t}\n</ng-template>\n", styles: [".hub-file-input__dropzone{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-height:var(--hub-file-input-min-height);padding:var(--hub-file-input-padding-y) var(--hub-file-input-padding-x);color:var(--hub-file-input-color);background-color:var(--hub-file-input-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-border-style) var(--hub-file-input-border-color);border-radius:var(--hub-file-input-border-radius);text-align:center;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__dropzone:hover{background-color:var(--hub-file-input-hover-bg);border-color:var(--hub-file-input-hover-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__dropzone--dragover,.hub-file-input__dropzone--dragover:hover{background-color:var(--hub-file-input-dragover-bg);border-color:var(--hub-file-input-dragover-border-color)}.hub-file-input__dropzone--invalid{border-color:var(--hub-form-invalid-border-color)}.hub-file-input__dropzone:has(.hub-file-input__native:disabled){cursor:not-allowed}.hub-file-input__dropzone:has(.hub-file-input__native:disabled):hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__native{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}.hub-file-input__icon{display:inline-flex;flex:0 0 auto;align-items:center;justify-content:center;width:var(--hub-file-input-icon-chip-size);height:var(--hub-file-input-icon-chip-size);background-color:var(--hub-file-input-icon-bg);border-radius:var(--hub-file-input-icon-chip-radius)}.hub-file-input__icon:before{content:\"\";width:var(--hub-file-input-icon-size);height:var(--hub-file-input-icon-size);background-color:var(--hub-file-input-icon-color);-webkit-mask:var(--hub-file-input-icon) center/contain no-repeat;mask:var(--hub-file-input-icon) center/contain no-repeat}.hub-file-input__prompt{display:flex;flex-direction:var(--hub-file-input-prompt-direction);flex-wrap:wrap;align-items:var(--hub-file-input-prompt-align);justify-content:center;gap:var(--hub-file-input-prompt-gap);color:var(--hub-file-input-prompt-color);font-size:var(--hub-file-input-prompt-font-size)}.hub-file-input__drop-text{color:var(--hub-file-input-drop-text-color);font-size:var(--hub-file-input-drop-text-font-size);font-weight:var(--hub-file-input-drop-text-font-weight)}.hub-file-input__drop-subtext{color:var(--hub-file-input-drop-subtext-color);font-size:var(--hub-file-input-drop-subtext-font-size)}.hub-file-input__browse{display:inline-flex;align-items:center;gap:var(--hub-file-input-browse-gap);margin-top:var(--hub-file-input-browse-margin-top);padding:var(--hub-file-input-browse-padding-y) var(--hub-file-input-browse-padding-x);color:var(--hub-file-input-browse-color);font-size:var(--hub-file-input-browse-font-size);font-weight:var(--hub-file-input-browse-font-weight);text-decoration:var(--hub-file-input-browse-text-decoration);background-color:var(--hub-file-input-browse-bg);border-radius:var(--hub-file-input-browse-radius);transition:var(--hub-file-input-transition)}.hub-file-input__browse:before{content:\"\";display:var(--hub-file-input-browse-icon-display);flex:0 0 auto;width:var(--hub-file-input-browse-icon-size);height:var(--hub-file-input-browse-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-browse-icon) center/contain no-repeat;mask:var(--hub-file-input-browse-icon) center/contain no-repeat}.hub-file-input__dropzone:hover .hub-file-input__browse{background-color:var(--hub-file-input-browse-hover-bg)}.hub-file-input__hint{color:var(--hub-file-input-hint-color);font-size:var(--hub-file-input-hint-font-size)}.hub-file-input__list{display:flex;flex-direction:column;gap:var(--hub-file-input-list-gap);margin:var(--hub-file-input-list-margin-top) 0 0;padding:0;list-style:none}.hub-file-input__list--grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap)}.hub-file-input__item{display:flex;align-items:center;gap:var(--hub-file-input-item-gap);padding:var(--hub-file-input-item-padding-y) var(--hub-file-input-item-padding-x);color:var(--hub-file-input-item-color);background-color:var(--hub-file-input-item-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-item-border-color);border-radius:var(--hub-file-input-item-border-radius);min-width:0}.hub-file-input__item[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__item[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__thumb{display:flex;flex:none;align-items:center;justify-content:center;width:var(--hub-file-input-thumb-size);height:var(--hub-file-input-thumb-size);overflow:hidden;background-color:var(--hub-file-input-thumb-bg);border-radius:var(--hub-file-input-thumb-radius)}.hub-file-input__image{width:100%;height:100%;object-fit:cover}.hub-file-input__file-icon{display:block;width:var(--hub-file-input-file-icon-size);height:var(--hub-file-input-file-icon-size);background-color:var(--hub-file-input-file-icon-color);-webkit-mask:var(--hub-file-input-file-icon) center/contain no-repeat;mask:var(--hub-file-input-file-icon) center/contain no-repeat}.hub-file-input__meta{display:flex;flex:1 1 auto;flex-direction:column;gap:.125rem;min-width:0}.hub-file-input__name{overflow:hidden;font-size:var(--hub-file-input-name-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__size{color:var(--hub-file-input-size-color);font-size:var(--hub-file-input-size-font-size)}.hub-file-input__error{color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size)}.hub-file-input__progress{display:block;width:100%;height:var(--hub-file-input-progress-height);overflow:hidden;background-color:var(--hub-file-input-progress-track-bg);border-radius:var(--hub-file-input-progress-radius)}.hub-file-input__progress-bar{display:block;width:calc(var(--hub-file-input-progress-value, 0) * 1%);height:100%;background-color:var(--hub-file-input-progress-bar-bg);border-radius:inherit;transition:width .15s linear}.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{width:33%;animation:hub-file-input-indeterminate var(--hub-file-input-progress-indeterminate-duration) ease-in-out infinite}.hub-file-input__actions{display:flex;flex:none;align-items:center;gap:.25rem}.hub-file-input__action{display:block;width:var(--hub-file-input-action-size);height:var(--hub-file-input-action-size);padding:0;background-color:var(--hub-file-input-action-color);border:0;cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__action:hover{background-color:var(--hub-file-input-action-hover-color)}.hub-file-input__action--remove{-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__action--remove:hover{background-color:var(--hub-file-input-remove-hover-color)}.hub-file-input__action--cancel{-webkit-mask:var(--hub-file-input-cancel-icon) center/contain no-repeat;mask:var(--hub-file-input-cancel-icon) center/contain no-repeat}.hub-file-input__action--retry{-webkit-mask:var(--hub-file-input-retry-icon) center/contain no-repeat;mask:var(--hub-file-input-retry-icon) center/contain no-repeat}.hub-file-input__clear{align-self:flex-start;margin-top:var(--hub-file-input-list-margin-top);padding:0;color:var(--hub-file-input-clear-color);font-size:var(--hub-file-input-clear-font-size);background:none;border:0;text-decoration:underline;cursor:pointer}.hub-file-input__item[data-status=done] .hub-file-input__size:after{display:inline-block;width:.75em;height:.75em;margin-inline-start:.375em;background-color:var(--hub-file-input-done-color);-webkit-mask:var(--hub-file-input-done-icon) center/contain no-repeat;mask:var(--hub-file-input-done-icon) center/contain no-repeat;content:\"\"}.hub-file-input__live{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__frame{position:relative}.hub-file-input__body--inline .hub-file-input__frame{width:var(--hub-file-input-inline-width);max-width:100%}.hub-file-input__body--inline .hub-file-input__dropzone{min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__frame:has(>.hub-file-input__native:focus-visible) .hub-file-input__dropzone{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__frame:has(>.hub-file-input__native:disabled) .hub-file-input__dropzone{cursor:not-allowed}.hub-file-input__tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--hub-file-input-grid-min-width),1fr));gap:var(--hub-file-input-grid-gap);margin:0;padding:0;list-style:none}.hub-file-input__dropzone+.hub-file-input__tiles{margin-top:var(--hub-file-input-list-margin-top)}.hub-file-input__tiles--single{display:block}.hub-file-input__tile{position:relative;display:flex;min-width:0;height:var(--hub-file-input-grid-thumb-height);overflow:hidden;color:var(--hub-file-input-color);background-color:var(--hub-file-input-tile-bg);border:var(--hub-file-input-border-width) var(--hub-file-input-tile-border-style) var(--hub-file-input-tile-border-color);border-radius:var(--hub-file-input-tile-radius);transition:var(--hub-file-input-transition)}.hub-file-input__tile[data-status=error]{border-color:var(--hub-file-input-error-color)}.hub-file-input__tile[data-status=done]{border-color:var(--hub-file-input-done-color)}.hub-file-input__tiles--single .hub-file-input__tile{height:auto;min-height:var(--hub-file-input-inline-min-height);aspect-ratio:var(--hub-file-input-inline-aspect-ratio)}.hub-file-input__tile--add{overflow:visible;background:none;border:0}.hub-file-input__dropzone--add{flex:1 1 auto;min-height:0;padding:var(--hub-file-input-tile-padding);border-radius:var(--hub-file-input-tile-radius)}.hub-file-input__tile-open{display:flex;flex:1 1 auto;flex-direction:column;align-items:center;justify-content:center;gap:var(--hub-file-input-gap);min-width:0;padding:var(--hub-file-input-tile-padding);color:inherit;font:inherit;text-decoration:none;background:none;border:0;cursor:pointer}.hub-file-input__tile-open:focus-visible{outline:none}.hub-file-input__tile:has(>.hub-file-input__tile-open:focus-visible){border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow)}.hub-file-input__tile-image{position:absolute;inset:0;width:100%;height:100%;padding:var(--hub-file-input-tile-padding);box-sizing:border-box;object-fit:var(--hub-file-input-tile-fit)}.hub-file-input__tile-file{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);max-width:100%;min-width:0}.hub-file-input__kind-icon{display:block;flex:none;width:var(--hub-file-input-kind-icon-size);height:var(--hub-file-input-kind-icon-size);background-color:var(--hub-file-input-kind-icon-color);-webkit-mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat;mask:var(--hub-file-input-kind-generic-icon) center/contain no-repeat}.hub-file-input__tile[data-file-kind=pdf] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-pdf-icon);mask-image:var(--hub-file-input-kind-pdf-icon)}.hub-file-input__tile[data-file-kind=document] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-document-icon);mask-image:var(--hub-file-input-kind-document-icon)}.hub-file-input__tile[data-file-kind=spreadsheet] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-spreadsheet-icon);mask-image:var(--hub-file-input-kind-spreadsheet-icon)}.hub-file-input__tile[data-file-kind=presentation] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-presentation-icon);mask-image:var(--hub-file-input-kind-presentation-icon)}.hub-file-input__tile[data-file-kind=archive] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-archive-icon);mask-image:var(--hub-file-input-kind-archive-icon)}.hub-file-input__tile[data-file-kind=audio] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-audio-icon);mask-image:var(--hub-file-input-kind-audio-icon)}.hub-file-input__tile[data-file-kind=video] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-video-icon);mask-image:var(--hub-file-input-kind-video-icon)}.hub-file-input__tile[data-file-kind=code] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-code-icon);mask-image:var(--hub-file-input-kind-code-icon)}.hub-file-input__tile[data-file-kind=image] .hub-file-input__kind-icon{-webkit-mask-image:var(--hub-file-input-kind-image-icon);mask-image:var(--hub-file-input-kind-image-icon)}.hub-file-input__tile-name{display:flex;max-width:100%;min-width:0;color:var(--hub-file-input-tile-name-color);font-size:var(--hub-file-input-tile-name-font-size)}.hub-file-input__tile-stem{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.hub-file-input__tile-ext{flex:none;white-space:nowrap}.hub-file-input__tile-veil{position:absolute;inset:0;background-color:var(--hub-file-input-tile-veil-bg);opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace{position:absolute;inset:0;display:inline-flex;align-items:center;gap:var(--hub-file-input-tile-replace-gap);width:fit-content;max-width:calc(100% - 2 * var(--hub-file-input-tile-padding));height:fit-content;margin:auto;padding:var(--hub-file-input-tile-replace-padding-y) var(--hub-file-input-tile-replace-padding-x);overflow:hidden;color:var(--hub-file-input-tile-replace-color);font-family:inherit;font-size:var(--hub-file-input-tile-replace-font-size);font-weight:var(--hub-file-input-browse-font-weight);line-height:1.5;white-space:nowrap;background-color:var(--hub-file-input-tile-replace-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-replace-border-color);border-radius:var(--hub-file-input-tile-replace-radius);box-shadow:var(--hub-file-input-tile-replace-shadow);cursor:pointer;opacity:0;pointer-events:none;transition:var(--hub-file-input-transition)}.hub-file-input__tile-replace:before{content:\"\";flex:none;width:var(--hub-file-input-tile-replace-icon-size);height:var(--hub-file-input-tile-replace-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat;mask:var(--hub-file-input-tile-replace-icon) center/contain no-repeat}.hub-file-input__tile-replace:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__tile--changeable:hover .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-veil{opacity:1}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-replace{opacity:1;pointer-events:auto}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-veil,.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-replace{opacity:1}.hub-file-input__tile--changeable:hover .hub-file-input__tile-file{opacity:0}.hub-file-input__tile--changeable:has(:focus-visible) .hub-file-input__tile-file{opacity:0}.hub-file-input__frame--dragover .hub-file-input__tiles--single .hub-file-input__tile--changeable .hub-file-input__tile-file{opacity:0}.hub-file-input__tile-progress{position:absolute;inset-inline:var(--hub-file-input-tile-padding);inset-block-end:var(--hub-file-input-tile-padding);width:auto}.hub-file-input__tile-error{position:absolute;inset-inline:0;inset-block-end:0;padding:var(--hub-ref-space-1, .25rem) var(--hub-file-input-tile-padding);overflow:hidden;color:var(--hub-file-input-error-color);font-size:var(--hub-file-input-error-font-size);text-overflow:ellipsis;white-space:nowrap;background-color:var(--hub-file-input-tile-error-bg)}.hub-file-input__tile-actions{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset);display:flex;gap:var(--hub-file-input-tile-action-gap)}.hub-file-input__chip{display:inline-flex;align-items:center;justify-content:center;width:var(--hub-file-input-tile-action-size);height:var(--hub-file-input-tile-action-size);padding:0;color:var(--hub-file-input-tile-action-color);background-color:var(--hub-file-input-tile-action-bg);border:var(--hub-file-input-border-width) solid var(--hub-file-input-tile-action-border-color);border-radius:var(--hub-file-input-tile-action-radius);box-shadow:var(--hub-file-input-tile-action-shadow);cursor:pointer;transition:var(--hub-file-input-transition)}.hub-file-input__chip:before{content:\"\";width:var(--hub-file-input-tile-action-icon-size);height:var(--hub-file-input-tile-action-icon-size);background-color:currentcolor;-webkit-mask:var(--hub-file-input-remove-icon) center/contain no-repeat;mask:var(--hub-file-input-remove-icon) center/contain no-repeat}.hub-file-input__chip:hover{color:var(--hub-file-input-tile-action-hover-color)}.hub-file-input__chip:focus-visible{border-color:var(--hub-file-input-focus-border-color);box-shadow:var(--hub-file-input-focus-box-shadow);outline:none}.hub-file-input__chip--remove:hover{color:var(--hub-file-input-tile-remove-hover-color)}.hub-file-input__chip--cancel:before{-webkit-mask-image:var(--hub-file-input-cancel-icon);mask-image:var(--hub-file-input-cancel-icon)}.hub-file-input__chip--retry:before{-webkit-mask-image:var(--hub-file-input-retry-icon);mask-image:var(--hub-file-input-retry-icon)}.hub-file-input__count{margin:var(--hub-file-input-list-margin-top) 0 0;color:var(--hub-file-input-count-color);font-size:var(--hub-file-input-count-font-size)}.hub-file-input__viewer{max-width:var(--hub-file-input-viewer-max-width);max-height:var(--hub-file-input-viewer-max-height);padding:var(--hub-file-input-viewer-padding);color:var(--hub-file-input-viewer-color);background-color:var(--hub-file-input-viewer-bg);border:0;border-radius:var(--hub-file-input-viewer-radius)}.hub-file-input__viewer::backdrop{background-color:var(--hub-file-input-viewer-backdrop, rgba(0, 0, 0, .7))}.hub-file-input__viewer .hub-file-input__chip--close{position:absolute;inset-block-start:var(--hub-file-input-tile-action-inset);inset-inline-end:var(--hub-file-input-tile-action-inset)}.hub-file-input__viewer-figure{display:flex;flex-direction:column;align-items:center;gap:var(--hub-file-input-gap);margin:0}.hub-file-input__viewer-image{display:block;max-width:100%;max-height:calc(var(--hub-file-input-viewer-max-height) - 5rem);object-fit:contain}.hub-file-input__viewer-caption{max-width:100%;padding-inline-end:var(--hub-file-input-tile-action-size);overflow:hidden;font-size:var(--hub-file-input-viewer-caption-font-size);text-overflow:ellipsis;white-space:nowrap}.hub-file-input__hint--hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}.hub-file-input__dropzone--readonly{cursor:default}.hub-file-input__dropzone--readonly:hover{background-color:var(--hub-file-input-bg);border-color:var(--hub-file-input-border-color)}.hub-file-input__list--grid .hub-file-input__item{flex-direction:column;align-items:stretch}.hub-file-input__list--grid .hub-file-input__thumb{width:100%;height:var(--hub-file-input-grid-thumb-height)}.hub-file-input__list--grid .hub-file-input__actions{justify-content:flex-end}@keyframes hub-file-input-indeterminate{0%{transform:translate(-100%)}to{transform:translate(300%)}}@media(prefers-reduced-motion:reduce){.hub-file-input__progress--indeterminate .hub-file-input__progress-bar{animation:none;width:100%;opacity:.5}}\n"] }]
|
|
11019
11019
|
}], propDecorators: { label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], labelType: [{ type: i0.Input, args: [{ isSignal: true, alias: "labelType", required: false }] }], multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSize", required: false }] }], minSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSize", required: false }] }], maxTotalSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTotalSize", required: false }] }], maxFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFiles", required: false }] }], dragDrop: [{ type: i0.Input, args: [{ isSignal: true, alias: "dragDrop", required: false }] }], paste: [{ type: i0.Input, args: [{ isSignal: true, alias: "paste", required: false }] }], preview: [{ type: i0.Input, args: [{ isSignal: true, alias: "preview", required: false }] }], currentFile: [{ type: i0.Input, args: [{ isSignal: true, alias: "currentFile", required: false }] }], imagePreview: [{ type: i0.Input, args: [{ isSignal: true, alias: "imagePreview", required: false }] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], allowDuplicates: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowDuplicates", required: false }] }], capture: [{ type: i0.Input, args: [{ isSignal: true, alias: "capture", required: false }] }], autoUpload: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoUpload", required: false }] }], buttonLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttonLabel", required: false }] }], dropText: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropText", required: false }] }], dropSubtext: [{ type: i0.Input, args: [{ isSignal: true, alias: "dropSubtext", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], classlist: [{ type: i0.Input, args: [{ isSignal: true, alias: "classlist", required: false }] }], valueChange: [{ type: i0.Output, args: ["valueChange"] }], rejected: [{ type: i0.Output, args: ["rejected"] }], fileRemoved: [{ type: i0.Output, args: ["fileRemoved"] }], currentFileRemoved: [{ type: i0.Output, args: ["currentFileRemoved"] }], uploadStateChange: [{ type: i0.Output, args: ["uploadStateChange"] }], nativeInput: [{ type: i0.ViewChild, args: ['nativeInput', { isSignal: true }] }], viewer: [{ type: i0.ViewChild, args: ['viewer', { isSignal: true }] }], iconTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileIconDirective), { isSignal: true }] }], previewTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFilePreviewDirective), { isSignal: true }] }], noticeTpt: [{ type: i0.ContentChild, args: [i0.forwardRef(() => HubFileDropzoneNoticeDirective), { isSignal: true }] }] } });
|
|
11020
11020
|
|
|
11021
11021
|
/**
|