dap-design-system 0.63.1 → 0.63.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"file-input.component.js","sources":["../../../src/components/file-input/file-input.component.ts"],"sourcesContent":["import clsx from 'clsx'\nimport { css, html, nothing, unsafeCSS } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { FileError, HttpError } from '@/common/errors'\nimport { CommonFormElementSize } from '@/common/types'\nimport { FileListElement } from '@/components/file-input/file-input-list-item.component'\nimport { GenericFormElement } from '@/internal/mixin/genericFormElement'\nimport { formLabelTemplate } from '@/internal/templates/formLabel'\nimport { i18next, t } from '@/localization/localization'\n\nimport DapDSButton from '../button/button.component'\nimport DapDSFeedback from '../feedback/feedback.component'\nimport DapDSFormLabel from '../form/form-label/form-label.component'\nimport DapDSIcon from '../icon/icon.component'\nimport DapDSIconButton from '../icon-button/icon-button.component'\nimport DapDSModal from '../modal/modal.component'\nimport DapDSTooltip from '../tooltip/tooltip.component'\nimport DapDSTypography from '../typography/typography.component'\nimport style from './file-input.scss?inline'\nimport DapDSFileInputList from './file-input-list.component'\nimport DapDSFileInputListItem from './file-input-list-item.component'\n\n/**\n * `dap-ds-file-input`\n * @summary A file input is a control that allows users to select files to upload.\n * @element dap-ds-file-input\n * @title - File input\n *\n * @property {string} name - The name of the file input.\n * @property {string} value - The value of the file input.\n * @property {'success' | 'error'} status - The status of the file input.\n * @property {string} label - The label for the file input.\n * @property {boolean} hideLabel - Visually hides the label while keeping it available to assistive technology. (default: false)\n * @property {string} description - The description for the file input.\n * @property {string} tooltip - The tooltip for the file input.\n * @property {'top' | 'right' | 'bottom' | 'left'} tooltipPlacement - The tooltip placement of the input.\n * @property {boolean} disabled - Whether the file input is disabled.\n * @property { 'xs' | 'sm' | 'lg' } size - The size of the file input.\n * @property {string} feedback - The feedback for the file input.\n * @property {'negative' | 'positive' | 'warning'} feedbackType - The type of feedback for the file input.\n * @property {boolean} required - Whether the file input is required.\n * @property {string} requiredLabel - The required indicator of the file input. (default: '*')\n * @property {boolean} optional - Whether the file input is optional.\n * @property {string} optionalLabel - The optional label of the file input.\n * @property {boolean} subtle - Font weight of the feedback label. Default is `false` which is bold.\n * @property {string} uploadButtonLabel - The label for the upload button.\n * @property {string} browseButtonLabel - The label for the browse button.\n * @property {string} accept - The file types that the file input accepts.\n * @property {boolean} multiple - Whether the file input accepts multiple files.\n * @property {boolean} keepValue - Whether to keep the value when new files are selected.\n * @property {string} uploadUrl - A remote URL to upload files to.\n * @property {string} deleteUrl - A remote URL to delete uploaded files from. Supports placeholders: `{fileName}`, `{id}`, `{key}`, `{location}`.\n * @property {string} uploadHeaders - Custom headers for upload requests (JSON string).\n * @property {string} deleteHeaders - Custom headers for delete requests (JSON string).\n * @property {boolean} autoupload - Whether to automatically upload files after selection.\n * @property {number} maxFiles - The maximum number of files that can be uploaded.\n * @property {number} maxFileSize - The maximum size of files that can be uploaded (in bytes).\n * @property {number} maxSizePerFile - The maximum size a single file can have (in bytes).\n * @property {string} maxFileSizeErrorText - Text for the max file size error.\n * @property {string} maxSizePerFileErrorText - Text for the max size per file error.\n * @property {string} maxFileAmountErrorText - Text for the max file amount error.\n * @property {string} fileTypeErrorText - Text for the file type error.\n * @property {boolean} showDropzone - Whether to show a separate dropzone area.\n * @property {string} dropzoneText - Text to display in the dropzone.\n * @property {string} dropzoneAriaLabel - Aria label for the dropzone.\n * @property {boolean} dropzoneFocusable - Whether the dropzone is in the tab order and exposes button keyboard behavior (default: true).\n * @property {boolean} showFileList - Whether to show the built-in file list.\n * @property {boolean} confirmRemove - Whether to show confirmation dialog before removing files.\n * @property {string} showUploadButton - Whether to show the upload button. Default is `true`.\n * @property {string} removeButtonLabel - The label for the remove button.\n * @property {string} cancelButtonLabel - The label for the cancel button.\n *\n * @event {{ file: File }} dds-upload-start - Fired when a file upload starts.\n * @event {{ file: File, progress: number }} dds-upload-progress - Fired during file upload progress.\n * @event {{ file: File, item: DapDSFileInputListItem, result: any }} dds-upload-complete - Fired when a file upload completes successfully.\n * @event {{ file?: File, errors: FileError[], item?: DapDSFileInputListItem }} dds-upload-error - Fired when a file upload encounters an error. Always contains an errors array, even if there is only one error.\n * @event {{ void }} dds-all-uploads-complete - Fired when all file uploads are complete.\n * @event {{ file: FileListElement }} dds-file-removed - Fired when a file is removed from the file input.\n * @event {{ file: FileListElement, error: Error }} dds-file-delete-error - Fired when a file deletion from server encounters an error.\n * @event {{ newFiles: File[], files: File[], canceledFiles: Set<File>, currentFiles: File[] }} dds-file-change - Fired when the file input value changes. This event is cancelable. Event detail contains: `newFiles` (just the files being added in this operation), `currentFiles` (all files that were already selected before this operation), `files` (all files after merge with existing when keepValue=true), and `canceledFiles` (Set to add files you want to reject). You can either: (1) Call `event.preventDefault()` to reject all files, or (2) Add specific files to `canceledFiles` to reject only those files.\n * @event {{ files: File[] }} dds-files-accepted - Fired when the file input value changes. This event is cancelable. Event detail contains: `files` (all files after merge with existing when keepValue=true).\n *\n * @slot dropzone-content - The content to display in the dropzone.\n *\n * @csspart base - The main file input container.\n * @csspart input - The file input control.\n * @csspart label - The file input label.\n * @csspart description - The file input description.\n * @csspart feedback - The file input feedback.\n * @csspart tooltip - The file input tooltip.\n * @csspart upload-progress - The upload progress container.\n * @csspart browse-button - The browse button.\n * @csspart upload-button - The upload button.\n * @csspart dropzone - The dropzone area.\n * @csspart label-base - The base of the label.\n * @csspart label-required - The required indicator of the label.\n * @csspart label-optional - The optional indicator of the label.\n *\n * @cssproperty --dds-file-input-holder-margin - The margin of the input holder in shorthand format: top right bottom left (default: var(--dds-spacing-400) 0 0 0)\n * @cssproperty --dds-file-input-dropzone-padding - The padding of the dropzone (default: var(--dds-spacing-800))\n * @cssproperty --dds-file-input-dropzone-border - The border of the dropzone in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-border-neutral-subtle))\n * @cssproperty --dds-file-input-dropzone-border-radius - The border radius of the dropzone (default: var(--dds-radius-base))\n * @cssproperty --dds-file-input-dropzone-background - The background of the dropzone (default: var(--dds-color-background-primary))\n * @cssproperty --dds-file-input-dropzone-border-hover - The border of the dropzone on hover in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-color-border-primary-hover))\n * @cssproperty --dds-file-input-dropzone-background-hover - The background of the dropzone on hover (default: var(--dds-color-background-primary-hover))\n * @cssproperty --dds-file-input-dropzone-border-dragover - The border of the dropzone when dragging over in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-color-border-accent))\n * @cssproperty --dds-file-input-dropzone-background-dragover - The background of the dropzone when dragging over (default: var(--dds-color-background-accent-light))\n * @cssproperty --dds-file-input-dropzone-border-disabled - The border of the disabled dropzone in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-border-neutral-disabled))\n * @cssproperty --dds-file-input-dropzone-gap - The gap between elements in the dropzone content (default: var(--dds-spacing-300))\n * @cssproperty --dds-file-input-dropzone-accept-color - The text color of the accepted file types in the dropzone (default: var(--dds-color-text-secondary))\n */\nexport default class DapDSFileInput extends GenericFormElement {\n static tagName = 'dap-ds-file-input'\n\n static dependencies = {\n 'dap-ds-form-label': DapDSFormLabel,\n 'dap-ds-tooltip': DapDSTooltip,\n 'dap-ds-icon-button': DapDSIconButton,\n 'dap-ds-icon': DapDSIcon,\n 'dap-ds-typography': DapDSTypography,\n 'dap-ds-button': DapDSButton,\n 'dap-ds-modal': DapDSModal,\n 'dap-ds-feedback': DapDSFeedback,\n }\n\n @query('#input') private readonly input!: HTMLInputElement\n\n /** Label for the upload button */\n @property() uploadButtonLabel: string\n\n /** Label for the browse button */\n @property() browseButtonLabel: string\n\n /** `data-testid` for the browse button. */\n @property() browseButtonTestId = 'file-input-browse-button'\n\n /** `data-testid` for the upload button. */\n @property() uploadButtonTestId = 'file-input-upload-button'\n\n /** Whether to show a separate dropzone area */\n @property({ type: Boolean }) showDropzone = false\n\n /** Text to display in the dropzone */\n @property() dropzoneText: string\n\n /** Whether to show the built-in file list */\n @property({ type: Boolean }) showFileList = false\n\n /** Whether to show confirmation dialog before removing files */\n @property({ type: Boolean }) confirmRemove = true\n\n /** Whether to show the upload button */\n @property({ type: String }) showUploadButton = 'true'\n\n /** Whether to show the browse button */\n @property({ type: String }) showBrowseButton = 'true'\n\n /** The file types that the file input accepts */\n @property() accept: string\n\n /** Whether the file input accepts multiple files. */\n @property({ type: Boolean }) multiple = false\n\n /** Whether to keep the value of the file input when new files are selected. */\n @property({ type: Boolean }) keepValue = false\n\n /** A remote URL to upload files to */\n @property() uploadUrl: string\n\n /** Whether to automatically upload files after selection */\n @property({ type: Boolean }) autoupload: boolean\n\n /** The property to use when uploading files */\n @property() uploadProperty = 'file'\n\n /** The HTTP method to use when uploading files */\n @property() uploadMethod = 'POST'\n\n /** A remote URL to delete uploaded files from */\n @property() deleteUrl: string\n\n /** The HTTP method to use when deleting files */\n @property() deleteMethod = 'DELETE'\n\n /** Whether to send credentials with the file upload request */\n @property({ type: Boolean }) withCredentials = false\n\n /** Custom headers to send with upload requests (JSON string) */\n @property() uploadHeaders: string\n\n /** Custom headers to send with delete requests (JSON string) */\n @property() deleteHeaders: string\n\n /** The file list component to bind to */\n @property({ attribute: false }) fileList: DapDSFileInputList | null = null\n\n /** The maximum number of files that can be uploaded */\n @property({ type: Number }) maxFiles?: number\n\n /** The maximum size of files that can be uploaded (in bytes) sum of all files */\n @property({ type: Number }) maxFileSize?: number\n\n /** The maximum size a single file can have (in bytes) */\n @property({ type: Number }) maxSizePerFile?: number\n\n /** Text for the max file size error */\n @property({ type: String }) maxFileSizeErrorText?: string\n\n /** Text for the max size per file error */\n @property({ type: String }) maxSizePerFileErrorText?: string\n\n /** Text for the max file amount error */\n @property({ type: String }) maxFileAmountErrorText?: string\n\n /** Text for the file type error */\n @property({ type: String }) fileTypeErrorText?: string\n\n /** The label for the remove button */\n @property() removeButtonLabel: string\n\n /** The label for the cancel button */\n @property() cancelButtonLabel: string\n\n /** Whether the remove button is dangerous */\n @property({ type: String }) removeButtonDanger = 'true'\n\n /** Whether to show thumbnail preview for supported file types in the built-in file list */\n @property({ type: String }) showThumbnail = 'true'\n\n /** Aria label for the dropzone */\n @property() dropzoneAriaLabel: string\n\n /**\n * When false, the dropzone is not tab-focusable (tabindex -1), uses role=\"group\"\n * instead of role=\"button\", and Enter/Space no longer opens the file dialog from\n * the dropzone. Click and drag-and-drop still work. When the browse button is\n * also hidden, slot a focusable control into dropzone-content to keep a keyboard\n * path to the file dialog — the hidden native input is out of the tab order\n * whenever a dropzone is rendered.\n */\n @property({ type: String }) dropzoneFocusable = 'true'\n\n /** Size of the thumbnail preview in the built-in file list */\n @property({ type: String })\n thumbnailSize: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' = 'sm'\n\n @property({ type: Array, attribute: false })\n get files() {\n return this._files\n }\n\n @state() private _files: File[] = []\n @state() private _uploadProgress: Record<string, number> = {}\n @state() private readonly _uploadingFiles: Set<string> = new Set()\n @state() private readonly _activeUploads: Map<string, XMLHttpRequest> =\n new Map()\n @state() private readonly _uploadedFiles: Map<string, any> = new Map() // Track uploaded files with their server response\n @state() private _isDragOver = false\n @state() private _showRemoveDialog = false\n @state() private _fileToRemove: File | null = null\n private _removeResolve: ((value: unknown) => void) | null = null\n private _removeReject: ((reason?: any) => void) | null = null\n\n static readonly styles = css`\n ${unsafeCSS(style)}\n `\n\n checkFileEquality(\n file1: File | FileListElement,\n file2: File | FileListElement,\n ) {\n return (\n file1.name === file2.name &&\n file1.size === file2.size &&\n file1.type === file2.type &&\n file1.lastModified === file2.lastModified\n )\n }\n\n /**\n * Validates if a file type is accepted based on the accept attribute\n */\n private validateFileType(file: File): boolean {\n if (!this.accept) return true\n\n const acceptedTypes = this.accept.split(',').map(type => type.trim())\n\n return acceptedTypes.some(acceptedType => {\n // Handle MIME types (e.g., \"image/jpeg\", \"text/*\")\n if (acceptedType.includes('/')) {\n if (acceptedType.endsWith('/*')) {\n const baseType = acceptedType.slice(0, -2)\n return file.type.startsWith(baseType)\n }\n return file.type === acceptedType\n }\n\n // Handle file extensions (e.g., \".jpg\", \".pdf\")\n if (acceptedType.startsWith('.')) {\n return file.name.toLowerCase().endsWith(acceptedType.toLowerCase())\n }\n\n return false\n })\n }\n\n public get focusElement() {\n return this.input\n }\n /**\n * Validates a file list against all constraints (count, size, type)\n */\n private validateFiles(fileList: FileList): {\n isValid: boolean\n errors?: Array<{\n file?: File\n message: string\n type: string\n meta?: Record<string, any>\n }>\n } {\n const errors: Array<{\n file?: File\n message: string\n type: string\n meta?: Record<string, any>\n }> = []\n\n // Check file count. With keepValue=false the incoming selection replaces the\n // current one, so the already selected files must not count towards the limit.\n const existingFileCount = this.keepValue ? this._files.length : 0\n\n if (this.maxFiles && fileList.length + existingFileCount > this.maxFiles) {\n for (const file of fileList) {\n errors.push({\n file: file,\n meta: {\n maxFiles: this.maxFiles,\n totalFiles: fileList.length + existingFileCount,\n },\n message:\n this.maxFileAmountErrorText ||\n t('fileInput.error.fileAmount', {\n count: this.maxFiles,\n }),\n type: 'maxFiles',\n })\n }\n }\n\n // Check file types and sizes\n let totalSize = 0\n for (const file of fileList) {\n // Validate file type\n if (!this.validateFileType(file)) {\n errors.push({\n file,\n meta: {\n type: this.accept,\n fileType: file.type,\n },\n message:\n this.fileTypeErrorText ||\n t('fileInput.error.fileType', {\n type: this.accept,\n }),\n type: 'fileType',\n })\n }\n\n if (this.maxSizePerFile && file.size > this.maxSizePerFile) {\n errors.push({\n file,\n meta: {\n maxSizePerFile: this.maxSizePerFile,\n fileSize: file.size,\n },\n message:\n this.maxSizePerFileErrorText ||\n t('fileInput.error.perFileSize', {\n size: Math.round(this.maxSizePerFile / 1024 / 1024),\n }),\n type: 'maxSizePerFile',\n })\n }\n\n // Validate file size\n totalSize += file.size\n if (this.maxFileSize && totalSize > this.maxFileSize) {\n errors.push({\n file,\n meta: {\n maxFileSize: this.maxFileSize,\n totalSize: totalSize,\n fileSize: file.size,\n },\n message:\n this.maxFileSizeErrorText ||\n t('fileInput.error.fileSize', {\n size: Math.round(this.maxFileSize / 1024 / 1024),\n }),\n type: 'maxFileSize',\n })\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n }\n\n /**\n * Removes a single file from the file input and frees up a slot in the\n * `maxFiles` budget.\n *\n * @param fileData The file to remove. It is matched against the selected files\n * by name, size, type and lastModified, so a structurally equal file also works.\n * @param options.skipConfirm Skips the built-in confirmation dialog for this\n * call only, without having to change the `confirmRemove` property. Useful when\n * the host application renders its own file list and already confirmed removal.\n */\n public removeFile(\n fileData: FileListElement | File,\n options?: { skipConfirm?: boolean },\n ): Promise<void> | void {\n if (this.confirmRemove && !options?.skipConfirm) {\n return new Promise((resolve, reject) => {\n this._removeResolve = resolve\n this._removeReject = reject\n this._showRemoveDialog = true\n this._fileToRemove = fileData as File\n })\n .then(() => {\n return this.performFileRemoval(fileData)\n })\n .catch(() => {\n // User cancelled - no action needed\n })\n } else {\n return this.performFileRemoval(fileData)\n }\n }\n\n /**\n * Removes every selected file, so the whole `maxFiles` budget becomes\n * available again.\n *\n * This is a programmatic API, so it never shows the confirmation dialog.\n * Files already uploaded are deleted from the server when `deleteUrl` is set,\n * and in-flight uploads are aborted.\n */\n public async clearFiles(): Promise<void> {\n const removedFiles = [...this._files]\n\n if (removedFiles.length === 0) return\n\n this.abortAllUploads()\n\n for (const file of removedFiles) {\n await this.deleteUploadedFileFromServer(file)\n }\n\n this._files = []\n this.value = undefined\n this.syncNativeInput()\n\n removedFiles.forEach(file => this.emit('dds-file-removed', { file }))\n this.emit('dds-file-change', {\n newFiles: [],\n files: this._files,\n canceledFiles: new Set(),\n currentFiles: this._files,\n })\n this.setValidity()\n this.emit('dds-files-accepted', { files: this._files })\n }\n\n /**\n * Deletes an already uploaded file from the server when a deleteUrl is set.\n * Delete failures are reported but never block the local removal.\n */\n private async deleteUploadedFileFromServer(fileData: FileListElement | File) {\n const fileName = fileData.name\n\n if (!this._uploadedFiles.has(fileName)) return\n\n try {\n const uploadResult = this._uploadedFiles.get(fileName)\n await this.deleteUploadedFile(fileName, uploadResult)\n this._uploadedFiles.delete(fileName)\n } catch (error) {\n // Emit delete error event but still remove from local list\n this.emit('dds-file-delete-error', { file: fileData, error })\n }\n }\n\n /** Keeps the native input element in sync with the current file list */\n private syncNativeInput() {\n if (!this.input) return\n\n if (this._files.length === 0) {\n // Also drops the underlying FileList, so the same file can be picked again\n this.input.value = ''\n return\n }\n\n if (typeof DataTransfer === 'undefined') return\n\n const dataTransfer = new DataTransfer()\n this._files.forEach(file => dataTransfer.items.add(file))\n this.input.files = dataTransfer.files\n }\n\n private async performFileRemoval(fileData: FileListElement | File) {\n this.abortUpload(fileData.name)\n\n await this.deleteUploadedFileFromServer(fileData)\n\n this._files = this._files.filter(\n (file: File) => !this.checkFileEquality(file, fileData),\n )\n\n this.syncNativeInput()\n\n if (this._files.length === 0 && this.required) {\n this.value = undefined\n }\n\n this.emit('dds-file-removed', { file: fileData })\n this.emit('dds-file-change', {\n newFiles: [],\n files: this._files,\n canceledFiles: new Set(),\n currentFiles: this._files,\n })\n this.setValidity()\n // Emit event with final accepted files after removal\n this.emit('dds-files-accepted', { files: this._files })\n }\n\n private languageChangeHandler = () => {\n // Force re-render when language changes to update translated text\n this.requestUpdate()\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n // Listen for language changes to update translated text\n i18next.on('languageChanged', this.languageChangeHandler)\n\n this.addEventListener('dds-file-remove', event => {\n const customEvent = event as CustomEvent\n this.removeFile(customEvent.detail.file)\n })\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n // Clean up language change listener\n i18next.off('languageChanged', this.languageChangeHandler)\n }\n\n async onConfirmDelete() {\n if (this._removeResolve) {\n this._removeResolve(true)\n }\n this._showRemoveDialog = false\n this._fileToRemove = null\n this._removeResolve = null\n this._removeReject = null\n }\n\n onCancelDelete() {\n if (this._removeReject) {\n this._removeReject(new Error('User cancelled'))\n }\n this._showRemoveDialog = false\n this._fileToRemove = null\n this._removeResolve = null\n this._removeReject = null\n }\n\n onCancel() {\n this.emit('dds-cancel')\n this.setValidity()\n }\n\n onClick() {\n if (this.disabled) return\n this.input.click()\n }\n\n onDropzoneKeydown(event: KeyboardEvent) {\n if (this.disabled || this.dropzoneFocusable === 'false') return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.input.click()\n }\n }\n\n setFileLoadingState(file: File, loading: boolean) {\n if (!this.fileList) {\n return\n }\n\n const fileComponent = this.fileList.getFileByName(\n file.name,\n )! as DapDSFileInputListItem\n\n fileComponent.loading = loading\n\n return fileComponent\n }\n\n /**\n * Aborts upload for a specific file\n */\n abortUpload(fileName: string) {\n const xhr = this._activeUploads.get(fileName)\n if (xhr) {\n xhr.abort()\n this._uploadingFiles.delete(fileName)\n this._activeUploads.delete(fileName)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[fileName]\n this._uploadProgress = newProgress\n }\n }\n\n /**\n * Aborts all active uploads\n */\n abortAllUploads() {\n this._activeUploads.forEach(xhr => {\n xhr.abort()\n })\n this._uploadingFiles.clear()\n this._activeUploads.clear()\n this._uploadProgress = {}\n }\n\n /**\n * Manually start upload of all selected files\n */\n startUpload() {\n if (this._files.length > 0 && this.uploadUrl) {\n this.uploadFiles(this._files)\n }\n }\n\n /**\n * Delete an uploaded file from the server\n */\n private async deleteUploadedFile(\n fileName: string,\n uploadResult: any,\n ): Promise<void> {\n if (!this.deleteUrl) {\n console.error('Delete URL is not configured')\n return\n }\n\n const xhr = new XMLHttpRequest()\n xhr.withCredentials = this.withCredentials\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve()\n } else {\n reject(\n new HttpError(\n `HTTP error! status: ${xhr.status}`,\n xhr.response,\n xhr.status,\n ),\n )\n }\n }\n xhr.onerror = () => {\n reject(new Error('Network error during file deletion'))\n }\n\n // Construct delete URL with multiple placeholder support\n let deleteEndpoint = this.deleteUrl\n\n // Replace common placeholders\n deleteEndpoint = deleteEndpoint.replace(\n '{fileName}',\n encodeURIComponent(fileName),\n )\n deleteEndpoint = deleteEndpoint.replace(\n '{filename}',\n encodeURIComponent(fileName),\n )\n\n // If uploadResult contains an ID or key, use that for deletion\n if (uploadResult && typeof uploadResult === 'object') {\n if (uploadResult.id) {\n deleteEndpoint = deleteEndpoint.replace(\n '{id}',\n encodeURIComponent(uploadResult.id),\n )\n }\n if (uploadResult.key) {\n deleteEndpoint = deleteEndpoint.replace(\n '{key}',\n encodeURIComponent(uploadResult.key),\n )\n }\n if (uploadResult.location) {\n deleteEndpoint = deleteEndpoint.replace(\n '{location}',\n encodeURIComponent(uploadResult.location),\n )\n }\n }\n\n xhr.open(this.deleteMethod, deleteEndpoint)\n\n // Add custom headers for delete\n if (this.deleteHeaders) {\n try {\n const headers = JSON.parse(this.deleteHeaders)\n Object.entries(headers).forEach(([key, value]) => {\n xhr.setRequestHeader(key, value as string)\n })\n } catch (error) {\n console.warn('Invalid deleteHeaders JSON:', this.deleteHeaders)\n }\n }\n\n // For S3 and most APIs, send minimal data for DELETE requests\n if (this.deleteMethod === 'DELETE') {\n // Some S3-compatible APIs might need the upload result for context\n if (uploadResult && (uploadResult.ETag || uploadResult.VersionId)) {\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(\n JSON.stringify({\n ETag: uploadResult.ETag,\n VersionId: uploadResult.VersionId,\n }),\n )\n } else {\n xhr.send()\n }\n } else {\n // For other HTTP methods, send the full upload result\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(JSON.stringify(uploadResult))\n }\n })\n }\n\n private async uploadFiles(files: File[]) {\n if (!this.uploadUrl) {\n console.error('Upload URL is not configured')\n return\n }\n\n const totalFiles = files.length\n let completedUploads = 0\n\n for (const file of files) {\n const formData = new FormData()\n formData.append(this.uploadProperty, file)\n\n try {\n let fileComponent: DapDSFileInputListItem | undefined = undefined\n\n // Track upload start\n this._uploadingFiles.add(file.name)\n this._uploadProgress = { ...this._uploadProgress, [file.name]: 0 }\n\n this.emit('dds-upload-start', { file })\n\n const xhr = new XMLHttpRequest()\n xhr.withCredentials = this.withCredentials\n\n // Store active upload for potential abortion\n this._activeUploads.set(file.name, xhr)\n\n xhr.open(this.uploadMethod, this.uploadUrl)\n\n // Add custom headers for upload\n if (this.uploadHeaders) {\n try {\n const headers = JSON.parse(this.uploadHeaders)\n Object.entries(headers).forEach(([key, value]) => {\n xhr.setRequestHeader(key, value as string)\n })\n } catch (error) {\n console.warn('Invalid uploadHeaders JSON:', this.uploadHeaders)\n }\n }\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n const progress = (event.loaded / event.total) * 100\n this._uploadProgress = {\n ...this._uploadProgress,\n [file.name]: progress,\n }\n\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, true)\n }\n\n this.emit('dds-upload-progress', {\n file,\n item: fileComponent,\n progress,\n })\n }\n }\n\n const response = await new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.response)\n } else {\n const error = new HttpError(\n `HTTP error! status: ${xhr.status}`,\n xhr.response,\n xhr.status,\n )\n reject(error)\n }\n }\n xhr.onerror = () => {\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, false)\n }\n\n reject(new Error('Network error'))\n }\n xhr.send(formData)\n })\n\n const result = JSON.parse(response as string)\n\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, false)\n }\n\n // Remove from uploading tracking\n this._uploadingFiles.delete(file.name)\n this._activeUploads.delete(file.name)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[file.name]\n this._uploadProgress = newProgress\n\n // Track uploaded file with its server response\n this._uploadedFiles.set(file.name, result)\n\n this.emit('dds-upload-complete', { file, item: fileComponent, result })\n\n completedUploads++\n if (completedUploads === totalFiles) {\n this.emit('dds-all-uploads-complete')\n }\n } catch (error) {\n // Remove from uploading tracking on error\n this._uploadingFiles.delete(file.name)\n this._activeUploads.delete(file.name)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[file.name]\n this._uploadProgress = newProgress\n\n // Convert error to FileError if it's not already one\n const fileError =\n error instanceof FileError\n ? error\n : new FileError(\n error instanceof Error ? error.message : String(error),\n file,\n error instanceof HttpError ? 'http' : 'upload',\n error instanceof HttpError\n ? { status: error.status, response: error.response }\n : undefined,\n )\n\n if (this.fileList) {\n const fileComponent = this.setFileLoadingState(file, false)\n this.emit('dds-upload-error', {\n file,\n item: fileComponent,\n errors: [fileError],\n })\n } else {\n this.emit('dds-upload-error', { file, errors: [fileError] })\n }\n }\n }\n }\n\n /**\n * Calculates what the new file list would be if the given files were added\n * Does not modify component state\n */\n private calculateNewFileList(fileList: FileList | null): File[] {\n if (!fileList || fileList.length === 0) {\n return []\n }\n\n const files = [...this._files]\n\n if (this.keepValue && this._files?.length) {\n Object.values(fileList).forEach((file: File) => {\n const isFileInList = !!this._files.find((f: File) =>\n this.checkFileEquality(f, file),\n )\n\n if (!isFileInList) {\n files.push(file)\n }\n })\n\n return files\n } else {\n return Object.values(fileList)\n }\n }\n\n private handleFileList(fileList: FileList | null) {\n const files = [...this._files]\n\n if (this.keepValue && this._files?.length) {\n Object.values(fileList!).forEach((file: File) => {\n const isFileInList = !!this._files.find((f: File) =>\n this.checkFileEquality(f, file),\n )\n\n if (!isFileInList) {\n files.push(file)\n }\n })\n\n this._files = files\n } else {\n this._files = fileList ? Object.values(fileList) : []\n }\n\n const dataTransfer = new DataTransfer()\n\n this._files.forEach(file => {\n dataTransfer.items.add(file)\n })\n this.input.files = dataTransfer.files\n\n if (this.autoupload) {\n this.uploadFiles(this._files)\n }\n }\n\n override onChange(event: InputEvent) {\n const target = event?.target as HTMLInputElement\n const targetFiles = target.files\n\n // If no files were selected (user canceled the dialog) and we have existing files,\n // just reset the input value and return early without processing or emitting events\n if ((!targetFiles || targetFiles.length === 0) && this._files.length > 0) {\n // Reset the input value to allow selecting the same file again if needed\n this.input.value = ''\n return\n }\n\n if (targetFiles) {\n const validation = this.validateFiles(targetFiles)\n if (!validation.isValid && validation.errors) {\n // Collect all validation errors into an array\n // All validation errors should have a file, but ensure we always create FileError\n const errors = validation.errors.map(error => {\n if (error.file) {\n return new FileError(\n error.message,\n error.file,\n error.type,\n error.meta,\n )\n } else {\n // Fallback: create a FileError with the first file if available\n // This should not happen in practice, but ensures type safety\n const fallbackFile =\n targetFiles.length > 0 ? targetFiles[0] : new File([], 'unknown')\n return new FileError(\n error.message,\n fallbackFile,\n error.type,\n error.meta,\n )\n }\n })\n\n // Emit all errors as a single array\n this.emit('dds-upload-error', { errors })\n return\n }\n }\n\n // Get the newly added files from the input\n const newFiles = targetFiles ? Array.from(targetFiles) : []\n\n // Calculate what the merged file list would be (existing + new)\n const allFiles = this.calculateNewFileList(targetFiles)\n\n // Create a Set for files that should be canceled\n const canceledFiles = new Set<File>()\n\n // Emit cancelable event with both new files and all files\n const changeEvent = this.emit(\n 'dds-file-change',\n { newFiles, files: allFiles, canceledFiles, currentFiles: this._files },\n { cancelable: true },\n )\n\n // If the event was prevented, reset the input and return\n if (changeEvent.defaultPrevented) {\n this.input.value = ''\n return\n }\n\n // Filter out canceled files from targetFiles\n if (canceledFiles.size > 0 && targetFiles) {\n const acceptedFiles = Array.from(targetFiles).filter(\n file => !canceledFiles.has(file),\n )\n\n // If all files were canceled, reset the input\n // if (acceptedFiles.length === 0) {\n // this.input.value = ''\n // return\n // }\n\n // Create a new FileList with only accepted files\n const dataTransfer = new DataTransfer()\n acceptedFiles.forEach(file => dataTransfer.items.add(file))\n\n this.value = this.input.value\n this.handleFileList(dataTransfer.files)\n this.setValidity()\n // Emit event with final accepted files after processing canceled files\n this.emit('dds-files-accepted', { files: this._files })\n } else {\n // No files were canceled, apply all changes\n this.value = this.input.value\n this.handleFileList(targetFiles)\n this.setValidity()\n // Emit event with final accepted files\n this.emit('dds-files-accepted', { files: this._files })\n }\n }\n\n onDragenter(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n this._isDragOver = true\n }\n\n onDragover(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n }\n\n onDragleave(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n\n if (!this.contains(event.relatedTarget as Node)) {\n this._isDragOver = false\n }\n }\n\n onDrop(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n this._isDragOver = false\n\n const droppedFiles = event.dataTransfer?.files\n if (droppedFiles) {\n const validation = this.validateFiles(droppedFiles)\n if (!validation.isValid && validation.errors) {\n // Collect all validation errors into an array\n // All validation errors should have a file, but ensure we always create FileError\n const errors = validation.errors.map(error => {\n if (error.file) {\n return new FileError(\n error.message,\n error.file,\n error.type,\n error.meta,\n )\n } else {\n // Fallback: create a FileError with the first file if available\n // This should not happen in practice, but ensures type safety\n const fallbackFile =\n droppedFiles.length > 0\n ? droppedFiles[0]\n : new File([], 'unknown')\n return new FileError(\n error.message,\n fallbackFile,\n error.type,\n error.meta,\n )\n }\n })\n\n // Emit all errors as a single array\n this.emit('dds-upload-error', { errors })\n return\n }\n }\n\n // Get the newly dropped files\n const newFiles = droppedFiles ? Array.from(droppedFiles) : []\n\n // Calculate what the merged file list would be (existing + new)\n const allFiles = this.calculateNewFileList(droppedFiles ?? null)\n\n // Create a Set for files that should be canceled\n const canceledFiles = new Set<File>()\n\n // Emit cancelable event with both new files and all files\n const changeEvent = this.emit(\n 'dds-file-change',\n { newFiles, files: allFiles, canceledFiles, currentFiles: this._files },\n { cancelable: true },\n )\n\n // If the event was prevented, return early without modifying state\n if (changeEvent.defaultPrevented) {\n return\n }\n\n // Filter out canceled files from droppedFiles\n if (canceledFiles.size > 0 && droppedFiles) {\n const acceptedFiles = Array.from(droppedFiles).filter(\n file => !canceledFiles.has(file),\n )\n\n // If all files were canceled, return early\n // if (acceptedFiles.length === 0) {\n // return\n // }\n\n // Create a new FileList with only accepted files\n const dataTransfer = new DataTransfer()\n acceptedFiles.forEach(file => dataTransfer.items.add(file))\n\n this.handleFileList(dataTransfer.files)\n this.setValidity()\n // Emit event with final accepted files after processing canceled files\n this.emit('dds-files-accepted', { files: this._files })\n } else {\n // No files were canceled, apply all changes\n this.handleFileList(droppedFiles ?? null)\n this.setValidity()\n // Emit event with final accepted files\n this.emit('dds-files-accepted', { files: this._files })\n }\n }\n\n render() {\n // The native input is the real keyboard control: the browse button is only\n // a tabindex=\"-1\" visual proxy for it. Without that proxy, the visually\n // hidden input would be an invisible tab stop, so it stays in the tab\n // order only while no dropzone is rendered. A rendered dropzone provides\n // the keyboard path instead: Enter/Space when focusable, or a focusable\n // control slotted into dropzone-content when dropzoneFocusable is false.\n const showBrowseButton =\n this.showBrowseButton === 'true' && !this.autoupload\n const inputTabbable = showBrowseButton || !this.showDropzone\n return html`\n <div class=\"label-container\">\n ${formLabelTemplate({\n label: this.label,\n id: 'label',\n htmlFor: 'input',\n size: this.size,\n required: this.required,\n requiredLabel: this.requiredLabel,\n optional: this.optional,\n optionalLabel: this.optionalLabel,\n disabled: this.disabled,\n noMargin: !!this.description,\n hideLabel: this.hideLabel,\n })}\n ${this.tooltip &&\n html` <dap-ds-tooltip\n part=\"tooltip\"\n content=${this.tooltip}\n mode=\"toggle\"\n floatingStrategy=\"fixed\"\n placement=${this.tooltipPlacement}>\n <dap-ds-icon-button\n clean\n class=\"info-button\"\n slot=\"trigger\"\n aria-label=${this.tooltipAriaLabel}\n size=${this.size as 'xs' | 'sm' | 'md' | 'lg'}\n iconSize=${this.size === 'xs' ? '16' : '22'}>\n <dap-ds-icon\n name=\"information-line\"\n class=\"info-button\"></dap-ds-icon>\n </dap-ds-icon-button>\n </dap-ds-tooltip>`}\n </div>\n ${this.description &&\n html`\n <dap-ds-typography\n part=\"description\"\n variant=\"description\"\n class=${clsx('input-description')}\n size=${ifDefined(this.size as CommonFormElementSize)}\n id=\"description\">\n ${this.description}\n </dap-ds-typography>\n `}\n ${this.showDropzone\n ? html`\n <div\n class=${clsx(\n 'dropzone',\n { 'dropzone--dragover': this._isDragOver },\n { 'dropzone--disabled': this.disabled },\n )}\n part=\"dropzone\"\n @dragenter=${this.onDragenter}\n @dragover=${this.onDragover}\n @dragleave=${this.onDragleave}\n @drop=${this.onDrop}\n @keydown=${this.dropzoneFocusable === 'true'\n ? this.onDropzoneKeydown\n : nothing}\n @click=${this.onClick}\n role=${this.dropzoneFocusable === 'true' ? 'button' : 'group'}\n aria-label=${ifDefined(this.dropzoneAriaLabel)}\n tabindex=${this.dropzoneFocusable === 'true' ? '0' : '-1'}>\n <slot name=\"dropzone-content\">\n <div class=\"dropzone__content\">\n <dap-ds-icon name=\"upload-2-line\" size=\"lg\"></dap-ds-icon>\n <dap-ds-typography variant=\"caption\">\n ${this.dropzoneText ||\n this.localize.t('fileInput.dropzone.text')}\n </dap-ds-typography>\n ${this.accept &&\n html`\n <dap-ds-typography\n variant=\"caption\"\n class=\"dropzone__accept\">\n ${this.localize.t('fileInput.dropzone.acceptedTypes')}:\n ${this.accept}\n </dap-ds-typography>\n `}\n </div>\n </slot>\n </div>\n `\n : nothing}\n <span\n part=\"base\"\n class=${clsx(\n 'input',\n { 'input--success': this.status === 'success' },\n { 'input--error': this.status === 'error' },\n { 'input--disabled': this.disabled },\n )}\n role=\"region\"\n aria-label=\"File upload area\">\n <div class=\"input__holder\" aria-describedby=\"drop-instructions\">\n <input\n id=\"input\"\n class=\"input__control sr-only\"\n part=\"input\"\n name=${this.name}\n type=\"file\"\n accept=${ifDefined(this.accept)}\n ?disabled=${this.disabled}\n ?multiple=${this.multiple}\n ?required=${this.required}\n tabindex=${inputTabbable ? '0' : '-1'}\n aria-labelledby=\"label\"\n aria-hidden=${inputTabbable ? 'false' : 'true'}\n aria-describedby=\"description ${this.feedback\n ? 'feedback'\n : nothing}\"\n @change=${this.onChange}\n @cancel=${this.onCancel}\n @invalid=${this.handleInvalid}\n @blur=${this.onBlur}\n @focus=${this.onFocus} />\n ${showBrowseButton\n ? html` <dap-ds-button\n class=\"input__button\"\n part=\"browse-button\"\n data-testid=${this.browseButtonTestId}\n tabindex=\"-1\"\n variant=\"outline\"\n ?disabled=${this.disabled}\n size=${ifDefined(this.size) as CommonFormElementSize}\n @click=${this.onClick}\n @dragenter=${this.showDropzone ? nothing : this.onDragenter}\n @dragover=${this.showDropzone ? nothing : this.onDragover}\n @drop=${this.showDropzone ? nothing : this.onDrop}\n aria-label=\"${this.browseButtonLabel ||\n this.localize.t('fileInput.browse')}${this.showDropzone\n ? ''\n : ` - ${this.localize.t('fileInput.dragDropArea')}`}\"\n role=\"button\"\n >${this.browseButtonLabel ||\n this.localize.t('fileInput.browse')}</dap-ds-button\n >`\n : nothing}\n ${this.showUploadButton === 'true' && !this.autoupload\n ? html`\n <dap-ds-button\n class=\"upload-button\"\n part=\"upload-button\"\n data-testid=${this.uploadButtonTestId}\n variant=\"primary\"\n size=${ifDefined(this.size) as CommonFormElementSize}\n ?disabled=${this._files.length === 0 ||\n !this.uploadUrl ||\n this._uploadingFiles.size > 0}\n @click=${this.startUpload}\n >${this.uploadButtonLabel ||\n this.localize.t('fileInput.upload')}</dap-ds-button\n >\n `\n : nothing}\n <div id=\"drop-instructions\" class=\"sr-only\">\n ${this.localize.t('fileInput.dragDropInstructions')}\n </div>\n </div>\n </span>\n ${!this.fileList && this._uploadingFiles.size > 0\n ? html`\n <div class=\"upload-progress\" part=\"upload-progress\">\n ${Array.from(this._uploadingFiles).map(fileName => {\n const progress = this._uploadProgress[fileName] || 0\n return html`\n <div class=\"upload-progress__item\">\n <dap-ds-typography variant=\"caption\">\n ${fileName} - ${Math.round(progress)}%\n </dap-ds-typography>\n <div class=\"upload-progress__bar\">\n <div\n class=\"upload-progress__fill\"\n style=\"width: ${progress}%\"></div>\n </div>\n </div>\n `\n })}\n </div>\n `\n : nothing}\n <dap-ds-modal\n .open=${this._showRemoveDialog}\n title=\"${this.localize.t('fileInput.removeDialog.title')}\"\n okButtonLabel=${this.removeButtonLabel ||\n this.localize.t('fileInput.removeDialog.confirm')}\n cancelButtonLabel=${this.cancelButtonLabel ||\n this.localize.t('fileInput.removeDialog.cancel')}\n .okButtonDanger=${this.removeButtonDanger === 'true'}\n @dds-cancel=${this.onCancelDelete}\n @dds-close=${this.onCancelDelete}\n @dds-ok=${this.onConfirmDelete}>\n <div>\n <dap-ds-typography variant=\"body\">\n ${this.localize.t('fileInput.removeDialog.message', {\n fileName: this._fileToRemove?.name ?? '',\n })}\n </dap-ds-typography>\n </div>\n </dap-ds-modal>\n\n ${this.feedback\n ? html`\n <dap-ds-feedback\n part=\"feedback\"\n feedbackType=${ifDefined(this.feedbackType)}\n feedbackSize=${ifDefined(this.size) as 'lg' | 'sm' | 'xs'}\n id=\"feedback\"\n .feedbackSubtle=${this.subtle}>\n ${this.feedback}\n </dap-ds-feedback>\n `\n : nothing}\n `\n }\n}\n"],"names":["_DapDSFileInput","GenericFormElement","file1","file2","file","type","acceptedType","baseType","fileList","errors","existingFileCount","t","totalSize","fileData","options","resolve","reject","__async","removedFiles","fileName","uploadResult","error","dataTransfer","i18next","event","customEvent","loading","fileComponent","xhr","newProgress","__spreadValues","HttpError","deleteEndpoint","headers","key","value","files","totalFiles","completedUploads","formData","__spreadProps","progress","response","result","fileError","FileError","_a","f","targetFiles","validation","fallbackFile","newFiles","allFiles","canceledFiles","acceptedFiles","droppedFiles","showBrowseButton","inputTabbable","html","formLabelTemplate","clsx","ifDefined","nothing","_b","DapDSFormLabel","DapDSTooltip","DapDSIconButton","DapDSIcon","DapDSTypography","DapDSButton","DapDSModal","DapDSFeedback","css","unsafeCSS","style","DapDSFileInput","__decorateClass","query","property","state"],"mappings":"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"}
1
+ {"version":3,"file":"file-input.component.js","sources":["../../../src/components/file-input/file-input.component.ts"],"sourcesContent":["import clsx from 'clsx'\nimport { css, html, nothing, unsafeCSS } from 'lit'\nimport { property, query, state } from 'lit/decorators.js'\nimport { ifDefined } from 'lit/directives/if-defined.js'\n\nimport { FileError, HttpError } from '@/common/errors'\nimport { CommonFormElementSize } from '@/common/types'\nimport { FileListElement } from '@/components/file-input/file-input-list-item.component'\nimport { GenericFormElement } from '@/internal/mixin/genericFormElement'\nimport { formLabelTemplate } from '@/internal/templates/formLabel'\nimport { i18next, t } from '@/localization/localization'\n\nimport DapDSButton from '../button/button.component'\nimport DapDSFeedback from '../feedback/feedback.component'\nimport DapDSFormLabel from '../form/form-label/form-label.component'\nimport DapDSIcon from '../icon/icon.component'\nimport DapDSIconButton from '../icon-button/icon-button.component'\nimport DapDSModal from '../modal/modal.component'\nimport DapDSTooltip from '../tooltip/tooltip.component'\nimport DapDSTypography from '../typography/typography.component'\nimport style from './file-input.scss?inline'\nimport DapDSFileInputList from './file-input-list.component'\nimport DapDSFileInputListItem from './file-input-list-item.component'\n\n/**\n * `dap-ds-file-input`\n * @summary A file input is a control that allows users to select files to upload.\n * @element dap-ds-file-input\n * @title - File input\n *\n * @property {string} name - The name of the file input.\n * @property {string} value - The value of the file input.\n * @property {'success' | 'error'} status - The status of the file input.\n * @property {string} label - The label for the file input.\n * @property {boolean} hideLabel - Visually hides the label while keeping it available to assistive technology. (default: false)\n * @property {string} description - The description for the file input.\n * @property {string} tooltip - The tooltip for the file input.\n * @property {'top' | 'right' | 'bottom' | 'left'} tooltipPlacement - The tooltip placement of the input.\n * @property {boolean} disabled - Whether the file input is disabled.\n * @property { 'xs' | 'sm' | 'lg' } size - The size of the file input.\n * @property {string} feedback - The feedback for the file input.\n * @property {'negative' | 'positive' | 'warning'} feedbackType - The type of feedback for the file input.\n * @property {boolean} required - Whether the file input is required.\n * @property {string} requiredLabel - The required indicator of the file input. (default: '*')\n * @property {boolean} optional - Whether the file input is optional.\n * @property {string} optionalLabel - The optional label of the file input.\n * @property {boolean} subtle - Font weight of the feedback label. Default is `false` which is bold.\n * @property {string} uploadButtonLabel - The label for the upload button.\n * @property {string} browseButtonLabel - The label for the browse button.\n * @property {string} accept - The file types that the file input accepts.\n * @property {boolean} multiple - Whether the file input accepts multiple files.\n * @property {boolean} keepValue - Whether to keep the value when new files are selected.\n * @property {string} uploadUrl - A remote URL to upload files to.\n * @property {string} deleteUrl - A remote URL to delete uploaded files from. Supports placeholders: `{fileName}`, `{id}`, `{key}`, `{location}`.\n * @property {string} uploadHeaders - Custom headers for upload requests (JSON string).\n * @property {string} deleteHeaders - Custom headers for delete requests (JSON string).\n * @property {boolean} autoupload - Whether to automatically upload files after selection.\n * @property {number} maxFiles - The maximum number of files that can be uploaded.\n * @property {number} maxFileSize - The maximum size of files that can be uploaded (in bytes).\n * @property {number} maxSizePerFile - The maximum size a single file can have (in bytes).\n * @property {string} maxFileSizeErrorText - Text for the max file size error.\n * @property {string} maxSizePerFileErrorText - Text for the max size per file error.\n * @property {string} maxFileAmountErrorText - Text for the max file amount error.\n * @property {string} fileTypeErrorText - Text for the file type error.\n * @property {boolean} showDropzone - Whether to show a separate dropzone area.\n * @property {string} dropzoneText - Text to display in the dropzone.\n * @property {string} dropzoneAriaLabel - Aria label for the dropzone.\n * @property {string} regionAriaLabel - Accessible name of the file upload region landmark. Defaults to the localized \"File upload area\" text.\n * @property {boolean} dropzoneFocusable - Whether the dropzone is in the tab order and exposes button keyboard behavior (default: true).\n * @property {boolean} showFileList - Whether to show the built-in file list.\n * @property {boolean} confirmRemove - Whether to show confirmation dialog before removing files.\n * @property {string} showUploadButton - Whether to show the upload button. Default is `true`.\n * @property {string} removeButtonLabel - The label for the remove button.\n * @property {string} cancelButtonLabel - The label for the cancel button.\n *\n * @event {{ file: File }} dds-upload-start - Fired when a file upload starts.\n * @event {{ file: File, progress: number }} dds-upload-progress - Fired during file upload progress.\n * @event {{ file: File, item: DapDSFileInputListItem, result: any }} dds-upload-complete - Fired when a file upload completes successfully.\n * @event {{ file?: File, errors: FileError[], item?: DapDSFileInputListItem }} dds-upload-error - Fired when a file upload encounters an error. Always contains an errors array, even if there is only one error.\n * @event {{ void }} dds-all-uploads-complete - Fired when all file uploads are complete.\n * @event {{ file: FileListElement }} dds-file-removed - Fired when a file is removed from the file input.\n * @event {{ file: FileListElement, error: Error }} dds-file-delete-error - Fired when a file deletion from server encounters an error.\n * @event {{ newFiles: File[], files: File[], canceledFiles: Set<File>, currentFiles: File[] }} dds-file-change - Fired when the file input value changes. This event is cancelable. Event detail contains: `newFiles` (just the files being added in this operation), `currentFiles` (all files that were already selected before this operation), `files` (all files after merge with existing when keepValue=true), and `canceledFiles` (Set to add files you want to reject). You can either: (1) Call `event.preventDefault()` to reject all files, or (2) Add specific files to `canceledFiles` to reject only those files.\n * @event {{ files: File[] }} dds-files-accepted - Fired when the file input value changes. This event is cancelable. Event detail contains: `files` (all files after merge with existing when keepValue=true).\n *\n * @slot dropzone-content - The content to display in the dropzone.\n *\n * @csspart base - The main file input container.\n * @csspart input - The file input control.\n * @csspart label - The file input label.\n * @csspart description - The file input description.\n * @csspart feedback - The file input feedback.\n * @csspart tooltip - The file input tooltip.\n * @csspart upload-progress - The upload progress container.\n * @csspart browse-button - The browse button.\n * @csspart upload-button - The upload button.\n * @csspart dropzone - The dropzone area.\n * @csspart label-base - The base of the label.\n * @csspart label-required - The required indicator of the label.\n * @csspart label-optional - The optional indicator of the label.\n *\n * @cssproperty --dds-file-input-holder-margin - The margin of the input holder in shorthand format: top right bottom left (default: var(--dds-spacing-400) 0 0 0)\n * @cssproperty --dds-file-input-dropzone-padding - The padding of the dropzone (default: var(--dds-spacing-800))\n * @cssproperty --dds-file-input-dropzone-border - The border of the dropzone in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-border-neutral-subtle))\n * @cssproperty --dds-file-input-dropzone-border-radius - The border radius of the dropzone (default: var(--dds-radius-base))\n * @cssproperty --dds-file-input-dropzone-background - The background of the dropzone (default: var(--dds-color-background-primary))\n * @cssproperty --dds-file-input-dropzone-border-hover - The border of the dropzone on hover in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-color-border-primary-hover))\n * @cssproperty --dds-file-input-dropzone-background-hover - The background of the dropzone on hover (default: var(--dds-color-background-primary-hover))\n * @cssproperty --dds-file-input-dropzone-border-dragover - The border of the dropzone when dragging over in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-color-border-accent))\n * @cssproperty --dds-file-input-dropzone-background-dragover - The background of the dropzone when dragging over (default: var(--dds-color-background-accent-light))\n * @cssproperty --dds-file-input-dropzone-border-disabled - The border of the disabled dropzone in shorthand format: width style color (default: var(--dds-border-width-base) dashed var(--dds-border-neutral-disabled))\n * @cssproperty --dds-file-input-dropzone-gap - The gap between elements in the dropzone content (default: var(--dds-spacing-300))\n * @cssproperty --dds-file-input-dropzone-accept-color - The text color of the accepted file types in the dropzone (default: var(--dds-color-text-secondary))\n */\nexport default class DapDSFileInput extends GenericFormElement {\n static tagName = 'dap-ds-file-input'\n\n static dependencies = {\n 'dap-ds-form-label': DapDSFormLabel,\n 'dap-ds-tooltip': DapDSTooltip,\n 'dap-ds-icon-button': DapDSIconButton,\n 'dap-ds-icon': DapDSIcon,\n 'dap-ds-typography': DapDSTypography,\n 'dap-ds-button': DapDSButton,\n 'dap-ds-modal': DapDSModal,\n 'dap-ds-feedback': DapDSFeedback,\n }\n\n @query('#input') private readonly input!: HTMLInputElement\n\n /** Label for the upload button */\n @property() uploadButtonLabel: string\n\n /** Label for the browse button */\n @property() browseButtonLabel: string\n\n /** `data-testid` for the browse button. */\n @property() browseButtonTestId = 'file-input-browse-button'\n\n /** `data-testid` for the upload button. */\n @property() uploadButtonTestId = 'file-input-upload-button'\n\n /** Whether to show a separate dropzone area */\n @property({ type: Boolean }) showDropzone = false\n\n /** Text to display in the dropzone */\n @property() dropzoneText: string\n\n /** Whether to show the built-in file list */\n @property({ type: Boolean }) showFileList = false\n\n /** Whether to show confirmation dialog before removing files */\n @property({ type: Boolean }) confirmRemove = true\n\n /** Whether to show the upload button */\n @property({ type: String }) showUploadButton = 'true'\n\n /** Whether to show the browse button */\n @property({ type: String }) showBrowseButton = 'true'\n\n /** The file types that the file input accepts */\n @property() accept: string\n\n /** Whether the file input accepts multiple files. */\n @property({ type: Boolean }) multiple = false\n\n /** Whether to keep the value of the file input when new files are selected. */\n @property({ type: Boolean }) keepValue = false\n\n /** A remote URL to upload files to */\n @property() uploadUrl: string\n\n /** Whether to automatically upload files after selection */\n @property({ type: Boolean }) autoupload: boolean\n\n /** The property to use when uploading files */\n @property() uploadProperty = 'file'\n\n /** The HTTP method to use when uploading files */\n @property() uploadMethod = 'POST'\n\n /** A remote URL to delete uploaded files from */\n @property() deleteUrl: string\n\n /** The HTTP method to use when deleting files */\n @property() deleteMethod = 'DELETE'\n\n /** Whether to send credentials with the file upload request */\n @property({ type: Boolean }) withCredentials = false\n\n /** Custom headers to send with upload requests (JSON string) */\n @property() uploadHeaders: string\n\n /** Custom headers to send with delete requests (JSON string) */\n @property() deleteHeaders: string\n\n /** The file list component to bind to */\n @property({ attribute: false }) fileList: DapDSFileInputList | null = null\n\n /** The maximum number of files that can be uploaded */\n @property({ type: Number }) maxFiles?: number\n\n /** The maximum size of files that can be uploaded (in bytes) sum of all files */\n @property({ type: Number }) maxFileSize?: number\n\n /** The maximum size a single file can have (in bytes) */\n @property({ type: Number }) maxSizePerFile?: number\n\n /** Text for the max file size error */\n @property({ type: String }) maxFileSizeErrorText?: string\n\n /** Text for the max size per file error */\n @property({ type: String }) maxSizePerFileErrorText?: string\n\n /** Text for the max file amount error */\n @property({ type: String }) maxFileAmountErrorText?: string\n\n /** Text for the file type error */\n @property({ type: String }) fileTypeErrorText?: string\n\n /** The label for the remove button */\n @property() removeButtonLabel: string\n\n /** The label for the cancel button */\n @property() cancelButtonLabel: string\n\n /** Whether the remove button is dangerous */\n @property({ type: String }) removeButtonDanger = 'true'\n\n /** Whether to show thumbnail preview for supported file types in the built-in file list */\n @property({ type: String }) showThumbnail = 'true'\n\n /** Aria label for the dropzone */\n @property() dropzoneAriaLabel: string\n\n /** Accessible name of the file upload region landmark. Defaults to the localized \"File upload area\" text. */\n @property() regionAriaLabel: string\n\n /**\n * When false, the dropzone is not tab-focusable (tabindex -1), uses role=\"group\"\n * instead of role=\"button\", and Enter/Space no longer opens the file dialog from\n * the dropzone. Click and drag-and-drop still work. When the browse button is\n * also hidden, slot a focusable control into dropzone-content to keep a keyboard\n * path to the file dialog — the hidden native input is out of the tab order\n * whenever a dropzone is rendered.\n */\n @property({ type: String }) dropzoneFocusable = 'true'\n\n /** Size of the thumbnail preview in the built-in file list */\n @property({ type: String })\n thumbnailSize: 'xxs' | 'xs' | 'sm' | 'md' | 'lg' = 'sm'\n\n @property({ type: Array, attribute: false })\n get files() {\n return this._files\n }\n\n @state() private _files: File[] = []\n @state() private _uploadProgress: Record<string, number> = {}\n @state() private readonly _uploadingFiles: Set<string> = new Set()\n @state() private readonly _activeUploads: Map<string, XMLHttpRequest> =\n new Map()\n @state() private readonly _uploadedFiles: Map<string, any> = new Map() // Track uploaded files with their server response\n @state() private _isDragOver = false\n @state() private _showRemoveDialog = false\n @state() private _fileToRemove: File | null = null\n private _removeResolve: ((value: unknown) => void) | null = null\n private _removeReject: ((reason?: any) => void) | null = null\n\n static readonly styles = css`\n ${unsafeCSS(style)}\n `\n\n checkFileEquality(\n file1: File | FileListElement,\n file2: File | FileListElement,\n ) {\n return (\n file1.name === file2.name &&\n file1.size === file2.size &&\n file1.type === file2.type &&\n file1.lastModified === file2.lastModified\n )\n }\n\n /**\n * Validates if a file type is accepted based on the accept attribute\n */\n private validateFileType(file: File): boolean {\n if (!this.accept) return true\n\n const acceptedTypes = this.accept.split(',').map(type => type.trim())\n\n return acceptedTypes.some(acceptedType => {\n // Handle MIME types (e.g., \"image/jpeg\", \"text/*\")\n if (acceptedType.includes('/')) {\n if (acceptedType.endsWith('/*')) {\n const baseType = acceptedType.slice(0, -2)\n return file.type.startsWith(baseType)\n }\n return file.type === acceptedType\n }\n\n // Handle file extensions (e.g., \".jpg\", \".pdf\")\n if (acceptedType.startsWith('.')) {\n return file.name.toLowerCase().endsWith(acceptedType.toLowerCase())\n }\n\n return false\n })\n }\n\n public get focusElement() {\n return this.input\n }\n /**\n * Validates a file list against all constraints (count, size, type)\n */\n private validateFiles(fileList: FileList): {\n isValid: boolean\n errors?: Array<{\n file?: File\n message: string\n type: string\n meta?: Record<string, any>\n }>\n } {\n const errors: Array<{\n file?: File\n message: string\n type: string\n meta?: Record<string, any>\n }> = []\n\n // Check file count. With keepValue=false the incoming selection replaces the\n // current one, so the already selected files must not count towards the limit.\n const existingFileCount = this.keepValue ? this._files.length : 0\n\n if (this.maxFiles && fileList.length + existingFileCount > this.maxFiles) {\n for (const file of fileList) {\n errors.push({\n file: file,\n meta: {\n maxFiles: this.maxFiles,\n totalFiles: fileList.length + existingFileCount,\n },\n message:\n this.maxFileAmountErrorText ||\n t('fileInput.error.fileAmount', {\n count: this.maxFiles,\n }),\n type: 'maxFiles',\n })\n }\n }\n\n // Check file types and sizes\n let totalSize = 0\n for (const file of fileList) {\n // Validate file type\n if (!this.validateFileType(file)) {\n errors.push({\n file,\n meta: {\n type: this.accept,\n fileType: file.type,\n },\n message:\n this.fileTypeErrorText ||\n t('fileInput.error.fileType', {\n type: this.accept,\n }),\n type: 'fileType',\n })\n }\n\n if (this.maxSizePerFile && file.size > this.maxSizePerFile) {\n errors.push({\n file,\n meta: {\n maxSizePerFile: this.maxSizePerFile,\n fileSize: file.size,\n },\n message:\n this.maxSizePerFileErrorText ||\n t('fileInput.error.perFileSize', {\n size: Math.round(this.maxSizePerFile / 1024 / 1024),\n }),\n type: 'maxSizePerFile',\n })\n }\n\n // Validate file size\n totalSize += file.size\n if (this.maxFileSize && totalSize > this.maxFileSize) {\n errors.push({\n file,\n meta: {\n maxFileSize: this.maxFileSize,\n totalSize: totalSize,\n fileSize: file.size,\n },\n message:\n this.maxFileSizeErrorText ||\n t('fileInput.error.fileSize', {\n size: Math.round(this.maxFileSize / 1024 / 1024),\n }),\n type: 'maxFileSize',\n })\n }\n }\n\n return {\n isValid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n }\n\n /**\n * Removes a single file from the file input and frees up a slot in the\n * `maxFiles` budget.\n *\n * @param fileData The file to remove. It is matched against the selected files\n * by name, size, type and lastModified, so a structurally equal file also works.\n * @param options.skipConfirm Skips the built-in confirmation dialog for this\n * call only, without having to change the `confirmRemove` property. Useful when\n * the host application renders its own file list and already confirmed removal.\n */\n public removeFile(\n fileData: FileListElement | File,\n options?: { skipConfirm?: boolean },\n ): Promise<void> | void {\n if (this.confirmRemove && !options?.skipConfirm) {\n return new Promise((resolve, reject) => {\n this._removeResolve = resolve\n this._removeReject = reject\n this._showRemoveDialog = true\n this._fileToRemove = fileData as File\n })\n .then(() => {\n return this.performFileRemoval(fileData)\n })\n .catch(() => {\n // User cancelled - no action needed\n })\n } else {\n return this.performFileRemoval(fileData)\n }\n }\n\n /**\n * Removes every selected file, so the whole `maxFiles` budget becomes\n * available again.\n *\n * This is a programmatic API, so it never shows the confirmation dialog.\n * Files already uploaded are deleted from the server when `deleteUrl` is set,\n * and in-flight uploads are aborted.\n */\n public async clearFiles(): Promise<void> {\n const removedFiles = [...this._files]\n\n if (removedFiles.length === 0) return\n\n this.abortAllUploads()\n\n for (const file of removedFiles) {\n await this.deleteUploadedFileFromServer(file)\n }\n\n this._files = []\n this.value = undefined\n this.syncNativeInput()\n\n removedFiles.forEach(file => this.emit('dds-file-removed', { file }))\n this.emit('dds-file-change', {\n newFiles: [],\n files: this._files,\n canceledFiles: new Set(),\n currentFiles: this._files,\n })\n this.setValidity()\n this.emit('dds-files-accepted', { files: this._files })\n }\n\n /**\n * Deletes an already uploaded file from the server when a deleteUrl is set.\n * Delete failures are reported but never block the local removal.\n */\n private async deleteUploadedFileFromServer(fileData: FileListElement | File) {\n const fileName = fileData.name\n\n if (!this._uploadedFiles.has(fileName)) return\n\n try {\n const uploadResult = this._uploadedFiles.get(fileName)\n await this.deleteUploadedFile(fileName, uploadResult)\n this._uploadedFiles.delete(fileName)\n } catch (error) {\n // Emit delete error event but still remove from local list\n this.emit('dds-file-delete-error', { file: fileData, error })\n }\n }\n\n /** Keeps the native input element in sync with the current file list */\n private syncNativeInput() {\n if (!this.input) return\n\n if (this._files.length === 0) {\n // Also drops the underlying FileList, so the same file can be picked again\n this.input.value = ''\n return\n }\n\n if (typeof DataTransfer === 'undefined') return\n\n const dataTransfer = new DataTransfer()\n this._files.forEach(file => dataTransfer.items.add(file))\n this.input.files = dataTransfer.files\n }\n\n private async performFileRemoval(fileData: FileListElement | File) {\n this.abortUpload(fileData.name)\n\n await this.deleteUploadedFileFromServer(fileData)\n\n this._files = this._files.filter(\n (file: File) => !this.checkFileEquality(file, fileData),\n )\n\n this.syncNativeInput()\n\n if (this._files.length === 0 && this.required) {\n this.value = undefined\n }\n\n this.emit('dds-file-removed', { file: fileData })\n this.emit('dds-file-change', {\n newFiles: [],\n files: this._files,\n canceledFiles: new Set(),\n currentFiles: this._files,\n })\n this.setValidity()\n // Emit event with final accepted files after removal\n this.emit('dds-files-accepted', { files: this._files })\n }\n\n private languageChangeHandler = () => {\n // Force re-render when language changes to update translated text\n this.requestUpdate()\n }\n\n connectedCallback() {\n super.connectedCallback()\n\n // Listen for language changes to update translated text\n i18next.on('languageChanged', this.languageChangeHandler)\n\n this.addEventListener('dds-file-remove', event => {\n const customEvent = event as CustomEvent\n this.removeFile(customEvent.detail.file)\n })\n }\n\n disconnectedCallback() {\n super.disconnectedCallback()\n // Clean up language change listener\n i18next.off('languageChanged', this.languageChangeHandler)\n }\n\n async onConfirmDelete() {\n if (this._removeResolve) {\n this._removeResolve(true)\n }\n this._showRemoveDialog = false\n this._fileToRemove = null\n this._removeResolve = null\n this._removeReject = null\n }\n\n onCancelDelete() {\n if (this._removeReject) {\n this._removeReject(new Error('User cancelled'))\n }\n this._showRemoveDialog = false\n this._fileToRemove = null\n this._removeResolve = null\n this._removeReject = null\n }\n\n onCancel() {\n this.emit('dds-cancel')\n this.setValidity()\n }\n\n onClick() {\n if (this.disabled) return\n this.input.click()\n }\n\n onDropzoneKeydown(event: KeyboardEvent) {\n if (this.disabled || this.dropzoneFocusable === 'false') return\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault()\n this.input.click()\n }\n }\n\n setFileLoadingState(file: File, loading: boolean) {\n if (!this.fileList) {\n return\n }\n\n const fileComponent = this.fileList.getFileByName(\n file.name,\n )! as DapDSFileInputListItem\n\n fileComponent.loading = loading\n\n return fileComponent\n }\n\n /**\n * Aborts upload for a specific file\n */\n abortUpload(fileName: string) {\n const xhr = this._activeUploads.get(fileName)\n if (xhr) {\n xhr.abort()\n this._uploadingFiles.delete(fileName)\n this._activeUploads.delete(fileName)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[fileName]\n this._uploadProgress = newProgress\n }\n }\n\n /**\n * Aborts all active uploads\n */\n abortAllUploads() {\n this._activeUploads.forEach(xhr => {\n xhr.abort()\n })\n this._uploadingFiles.clear()\n this._activeUploads.clear()\n this._uploadProgress = {}\n }\n\n /**\n * Manually start upload of all selected files\n */\n startUpload() {\n if (this._files.length > 0 && this.uploadUrl) {\n this.uploadFiles(this._files)\n }\n }\n\n /**\n * Delete an uploaded file from the server\n */\n private async deleteUploadedFile(\n fileName: string,\n uploadResult: any,\n ): Promise<void> {\n if (!this.deleteUrl) {\n console.error('Delete URL is not configured')\n return\n }\n\n const xhr = new XMLHttpRequest()\n xhr.withCredentials = this.withCredentials\n\n return new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve()\n } else {\n reject(\n new HttpError(\n `HTTP error! status: ${xhr.status}`,\n xhr.response,\n xhr.status,\n ),\n )\n }\n }\n xhr.onerror = () => {\n reject(new Error('Network error during file deletion'))\n }\n\n // Construct delete URL with multiple placeholder support\n let deleteEndpoint = this.deleteUrl\n\n // Replace common placeholders\n deleteEndpoint = deleteEndpoint.replace(\n '{fileName}',\n encodeURIComponent(fileName),\n )\n deleteEndpoint = deleteEndpoint.replace(\n '{filename}',\n encodeURIComponent(fileName),\n )\n\n // If uploadResult contains an ID or key, use that for deletion\n if (uploadResult && typeof uploadResult === 'object') {\n if (uploadResult.id) {\n deleteEndpoint = deleteEndpoint.replace(\n '{id}',\n encodeURIComponent(uploadResult.id),\n )\n }\n if (uploadResult.key) {\n deleteEndpoint = deleteEndpoint.replace(\n '{key}',\n encodeURIComponent(uploadResult.key),\n )\n }\n if (uploadResult.location) {\n deleteEndpoint = deleteEndpoint.replace(\n '{location}',\n encodeURIComponent(uploadResult.location),\n )\n }\n }\n\n xhr.open(this.deleteMethod, deleteEndpoint)\n\n // Add custom headers for delete\n if (this.deleteHeaders) {\n try {\n const headers = JSON.parse(this.deleteHeaders)\n Object.entries(headers).forEach(([key, value]) => {\n xhr.setRequestHeader(key, value as string)\n })\n } catch (error) {\n console.warn('Invalid deleteHeaders JSON:', this.deleteHeaders)\n }\n }\n\n // For S3 and most APIs, send minimal data for DELETE requests\n if (this.deleteMethod === 'DELETE') {\n // Some S3-compatible APIs might need the upload result for context\n if (uploadResult && (uploadResult.ETag || uploadResult.VersionId)) {\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(\n JSON.stringify({\n ETag: uploadResult.ETag,\n VersionId: uploadResult.VersionId,\n }),\n )\n } else {\n xhr.send()\n }\n } else {\n // For other HTTP methods, send the full upload result\n xhr.setRequestHeader('Content-Type', 'application/json')\n xhr.send(JSON.stringify(uploadResult))\n }\n })\n }\n\n private async uploadFiles(files: File[]) {\n if (!this.uploadUrl) {\n console.error('Upload URL is not configured')\n return\n }\n\n const totalFiles = files.length\n let completedUploads = 0\n\n for (const file of files) {\n const formData = new FormData()\n formData.append(this.uploadProperty, file)\n\n try {\n let fileComponent: DapDSFileInputListItem | undefined = undefined\n\n // Track upload start\n this._uploadingFiles.add(file.name)\n this._uploadProgress = { ...this._uploadProgress, [file.name]: 0 }\n\n this.emit('dds-upload-start', { file })\n\n const xhr = new XMLHttpRequest()\n xhr.withCredentials = this.withCredentials\n\n // Store active upload for potential abortion\n this._activeUploads.set(file.name, xhr)\n\n xhr.open(this.uploadMethod, this.uploadUrl)\n\n // Add custom headers for upload\n if (this.uploadHeaders) {\n try {\n const headers = JSON.parse(this.uploadHeaders)\n Object.entries(headers).forEach(([key, value]) => {\n xhr.setRequestHeader(key, value as string)\n })\n } catch (error) {\n console.warn('Invalid uploadHeaders JSON:', this.uploadHeaders)\n }\n }\n\n xhr.upload.onprogress = event => {\n if (event.lengthComputable) {\n const progress = (event.loaded / event.total) * 100\n this._uploadProgress = {\n ...this._uploadProgress,\n [file.name]: progress,\n }\n\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, true)\n }\n\n this.emit('dds-upload-progress', {\n file,\n item: fileComponent,\n progress,\n })\n }\n }\n\n const response = await new Promise((resolve, reject) => {\n xhr.onload = () => {\n if (xhr.status >= 200 && xhr.status < 300) {\n resolve(xhr.response)\n } else {\n const error = new HttpError(\n `HTTP error! status: ${xhr.status}`,\n xhr.response,\n xhr.status,\n )\n reject(error)\n }\n }\n xhr.onerror = () => {\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, false)\n }\n\n reject(new Error('Network error'))\n }\n xhr.send(formData)\n })\n\n const result = JSON.parse(response as string)\n\n if (this.fileList) {\n fileComponent = this.setFileLoadingState(file, false)\n }\n\n // Remove from uploading tracking\n this._uploadingFiles.delete(file.name)\n this._activeUploads.delete(file.name)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[file.name]\n this._uploadProgress = newProgress\n\n // Track uploaded file with its server response\n this._uploadedFiles.set(file.name, result)\n\n this.emit('dds-upload-complete', { file, item: fileComponent, result })\n\n completedUploads++\n if (completedUploads === totalFiles) {\n this.emit('dds-all-uploads-complete')\n }\n } catch (error) {\n // Remove from uploading tracking on error\n this._uploadingFiles.delete(file.name)\n this._activeUploads.delete(file.name)\n const newProgress = { ...this._uploadProgress }\n delete newProgress[file.name]\n this._uploadProgress = newProgress\n\n // Convert error to FileError if it's not already one\n const fileError =\n error instanceof FileError\n ? error\n : new FileError(\n error instanceof Error ? error.message : String(error),\n file,\n error instanceof HttpError ? 'http' : 'upload',\n error instanceof HttpError\n ? { status: error.status, response: error.response }\n : undefined,\n )\n\n if (this.fileList) {\n const fileComponent = this.setFileLoadingState(file, false)\n this.emit('dds-upload-error', {\n file,\n item: fileComponent,\n errors: [fileError],\n })\n } else {\n this.emit('dds-upload-error', { file, errors: [fileError] })\n }\n }\n }\n }\n\n /**\n * Calculates what the new file list would be if the given files were added\n * Does not modify component state\n */\n private calculateNewFileList(fileList: FileList | null): File[] {\n if (!fileList || fileList.length === 0) {\n return []\n }\n\n const files = [...this._files]\n\n if (this.keepValue && this._files?.length) {\n Object.values(fileList).forEach((file: File) => {\n const isFileInList = !!this._files.find((f: File) =>\n this.checkFileEquality(f, file),\n )\n\n if (!isFileInList) {\n files.push(file)\n }\n })\n\n return files\n } else {\n return Object.values(fileList)\n }\n }\n\n private handleFileList(fileList: FileList | null) {\n const files = [...this._files]\n\n if (this.keepValue && this._files?.length) {\n Object.values(fileList!).forEach((file: File) => {\n const isFileInList = !!this._files.find((f: File) =>\n this.checkFileEquality(f, file),\n )\n\n if (!isFileInList) {\n files.push(file)\n }\n })\n\n this._files = files\n } else {\n this._files = fileList ? Object.values(fileList) : []\n }\n\n const dataTransfer = new DataTransfer()\n\n this._files.forEach(file => {\n dataTransfer.items.add(file)\n })\n this.input.files = dataTransfer.files\n\n if (this.autoupload) {\n this.uploadFiles(this._files)\n }\n }\n\n override onChange(event: InputEvent) {\n const target = event?.target as HTMLInputElement\n const targetFiles = target.files\n\n // If no files were selected (user canceled the dialog) and we have existing files,\n // just reset the input value and return early without processing or emitting events\n if ((!targetFiles || targetFiles.length === 0) && this._files.length > 0) {\n // Reset the input value to allow selecting the same file again if needed\n this.input.value = ''\n return\n }\n\n if (targetFiles) {\n const validation = this.validateFiles(targetFiles)\n if (!validation.isValid && validation.errors) {\n // Collect all validation errors into an array\n // All validation errors should have a file, but ensure we always create FileError\n const errors = validation.errors.map(error => {\n if (error.file) {\n return new FileError(\n error.message,\n error.file,\n error.type,\n error.meta,\n )\n } else {\n // Fallback: create a FileError with the first file if available\n // This should not happen in practice, but ensures type safety\n const fallbackFile =\n targetFiles.length > 0 ? targetFiles[0] : new File([], 'unknown')\n return new FileError(\n error.message,\n fallbackFile,\n error.type,\n error.meta,\n )\n }\n })\n\n // Emit all errors as a single array\n this.emit('dds-upload-error', { errors })\n return\n }\n }\n\n // Get the newly added files from the input\n const newFiles = targetFiles ? Array.from(targetFiles) : []\n\n // Calculate what the merged file list would be (existing + new)\n const allFiles = this.calculateNewFileList(targetFiles)\n\n // Create a Set for files that should be canceled\n const canceledFiles = new Set<File>()\n\n // Emit cancelable event with both new files and all files\n const changeEvent = this.emit(\n 'dds-file-change',\n { newFiles, files: allFiles, canceledFiles, currentFiles: this._files },\n { cancelable: true },\n )\n\n // If the event was prevented, reset the input and return\n if (changeEvent.defaultPrevented) {\n this.input.value = ''\n return\n }\n\n // Filter out canceled files from targetFiles\n if (canceledFiles.size > 0 && targetFiles) {\n const acceptedFiles = Array.from(targetFiles).filter(\n file => !canceledFiles.has(file),\n )\n\n // If all files were canceled, reset the input\n // if (acceptedFiles.length === 0) {\n // this.input.value = ''\n // return\n // }\n\n // Create a new FileList with only accepted files\n const dataTransfer = new DataTransfer()\n acceptedFiles.forEach(file => dataTransfer.items.add(file))\n\n this.value = this.input.value\n this.handleFileList(dataTransfer.files)\n this.setValidity()\n // Emit event with final accepted files after processing canceled files\n this.emit('dds-files-accepted', { files: this._files })\n } else {\n // No files were canceled, apply all changes\n this.value = this.input.value\n this.handleFileList(targetFiles)\n this.setValidity()\n // Emit event with final accepted files\n this.emit('dds-files-accepted', { files: this._files })\n }\n }\n\n onDragenter(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n this._isDragOver = true\n }\n\n onDragover(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n }\n\n onDragleave(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n\n if (!this.contains(event.relatedTarget as Node)) {\n this._isDragOver = false\n }\n }\n\n onDrop(event: DragEvent) {\n if (this.disabled) return\n event.preventDefault()\n this._isDragOver = false\n\n const droppedFiles = event.dataTransfer?.files\n if (droppedFiles) {\n const validation = this.validateFiles(droppedFiles)\n if (!validation.isValid && validation.errors) {\n // Collect all validation errors into an array\n // All validation errors should have a file, but ensure we always create FileError\n const errors = validation.errors.map(error => {\n if (error.file) {\n return new FileError(\n error.message,\n error.file,\n error.type,\n error.meta,\n )\n } else {\n // Fallback: create a FileError with the first file if available\n // This should not happen in practice, but ensures type safety\n const fallbackFile =\n droppedFiles.length > 0\n ? droppedFiles[0]\n : new File([], 'unknown')\n return new FileError(\n error.message,\n fallbackFile,\n error.type,\n error.meta,\n )\n }\n })\n\n // Emit all errors as a single array\n this.emit('dds-upload-error', { errors })\n return\n }\n }\n\n // Get the newly dropped files\n const newFiles = droppedFiles ? Array.from(droppedFiles) : []\n\n // Calculate what the merged file list would be (existing + new)\n const allFiles = this.calculateNewFileList(droppedFiles ?? null)\n\n // Create a Set for files that should be canceled\n const canceledFiles = new Set<File>()\n\n // Emit cancelable event with both new files and all files\n const changeEvent = this.emit(\n 'dds-file-change',\n { newFiles, files: allFiles, canceledFiles, currentFiles: this._files },\n { cancelable: true },\n )\n\n // If the event was prevented, return early without modifying state\n if (changeEvent.defaultPrevented) {\n return\n }\n\n // Filter out canceled files from droppedFiles\n if (canceledFiles.size > 0 && droppedFiles) {\n const acceptedFiles = Array.from(droppedFiles).filter(\n file => !canceledFiles.has(file),\n )\n\n // If all files were canceled, return early\n // if (acceptedFiles.length === 0) {\n // return\n // }\n\n // Create a new FileList with only accepted files\n const dataTransfer = new DataTransfer()\n acceptedFiles.forEach(file => dataTransfer.items.add(file))\n\n this.handleFileList(dataTransfer.files)\n this.setValidity()\n // Emit event with final accepted files after processing canceled files\n this.emit('dds-files-accepted', { files: this._files })\n } else {\n // No files were canceled, apply all changes\n this.handleFileList(droppedFiles ?? null)\n this.setValidity()\n // Emit event with final accepted files\n this.emit('dds-files-accepted', { files: this._files })\n }\n }\n\n render() {\n // The native input is the real keyboard control: the browse button is only\n // a tabindex=\"-1\" visual proxy for it. Without that proxy, the visually\n // hidden input would be an invisible tab stop, so it stays in the tab\n // order only while no dropzone is rendered. A rendered dropzone provides\n // the keyboard path instead: Enter/Space when focusable, or a focusable\n // control slotted into dropzone-content when dropzoneFocusable is false.\n const showBrowseButton =\n this.showBrowseButton === 'true' && !this.autoupload\n const inputTabbable = showBrowseButton || !this.showDropzone\n return html`\n <div class=\"label-container\">\n ${formLabelTemplate({\n label: this.label,\n id: 'label',\n htmlFor: 'input',\n size: this.size,\n required: this.required,\n requiredLabel: this.requiredLabel,\n optional: this.optional,\n optionalLabel: this.optionalLabel,\n disabled: this.disabled,\n noMargin: !!this.description,\n hideLabel: this.hideLabel,\n })}\n ${this.tooltip &&\n html` <dap-ds-tooltip\n part=\"tooltip\"\n content=${this.tooltip}\n mode=\"toggle\"\n floatingStrategy=\"fixed\"\n placement=${this.tooltipPlacement}>\n <dap-ds-icon-button\n clean\n class=\"info-button\"\n slot=\"trigger\"\n aria-label=${this.tooltipAriaLabel}\n size=${this.size as 'xs' | 'sm' | 'md' | 'lg'}\n iconSize=${this.size === 'xs' ? '16' : '22'}>\n <dap-ds-icon\n name=\"information-line\"\n class=\"info-button\"></dap-ds-icon>\n </dap-ds-icon-button>\n </dap-ds-tooltip>`}\n </div>\n ${this.description &&\n html`\n <dap-ds-typography\n part=\"description\"\n variant=\"description\"\n class=${clsx('input-description')}\n size=${ifDefined(this.size as CommonFormElementSize)}\n id=\"description\">\n ${this.description}\n </dap-ds-typography>\n `}\n ${this.showDropzone\n ? html`\n <div\n class=${clsx(\n 'dropzone',\n { 'dropzone--dragover': this._isDragOver },\n { 'dropzone--disabled': this.disabled },\n )}\n part=\"dropzone\"\n @dragenter=${this.onDragenter}\n @dragover=${this.onDragover}\n @dragleave=${this.onDragleave}\n @drop=${this.onDrop}\n @keydown=${this.dropzoneFocusable === 'true'\n ? this.onDropzoneKeydown\n : nothing}\n @click=${this.onClick}\n role=${this.dropzoneFocusable === 'true' ? 'button' : 'group'}\n aria-label=${ifDefined(this.dropzoneAriaLabel)}\n tabindex=${this.dropzoneFocusable === 'true' ? '0' : '-1'}>\n <slot name=\"dropzone-content\">\n <div class=\"dropzone__content\">\n <dap-ds-icon name=\"upload-2-line\" size=\"lg\"></dap-ds-icon>\n <dap-ds-typography variant=\"caption\">\n ${this.dropzoneText ||\n this.localize.t('fileInput.dropzone.text')}\n </dap-ds-typography>\n ${this.accept &&\n html`\n <dap-ds-typography\n variant=\"caption\"\n class=\"dropzone__accept\">\n ${this.localize.t('fileInput.dropzone.acceptedTypes')}:\n ${this.accept}\n </dap-ds-typography>\n `}\n </div>\n </slot>\n </div>\n `\n : nothing}\n <span\n part=\"base\"\n class=${clsx(\n 'input',\n { 'input--success': this.status === 'success' },\n { 'input--error': this.status === 'error' },\n { 'input--disabled': this.disabled },\n )}\n role=\"region\"\n aria-label=${this.regionAriaLabel ||\n this.localize.t('fileInput.uploadArea')}>\n <div class=\"input__holder\" aria-describedby=\"drop-instructions\">\n <input\n id=\"input\"\n class=\"input__control sr-only\"\n part=\"input\"\n name=${this.name}\n type=\"file\"\n accept=${ifDefined(this.accept)}\n ?disabled=${this.disabled}\n ?multiple=${this.multiple}\n ?required=${this.required}\n tabindex=${inputTabbable ? '0' : '-1'}\n aria-labelledby=\"label\"\n aria-hidden=${inputTabbable ? 'false' : 'true'}\n aria-describedby=\"description ${this.feedback\n ? 'feedback'\n : nothing}\"\n @change=${this.onChange}\n @cancel=${this.onCancel}\n @invalid=${this.handleInvalid}\n @blur=${this.onBlur}\n @focus=${this.onFocus} />\n ${showBrowseButton\n ? html` <dap-ds-button\n class=\"input__button\"\n part=\"browse-button\"\n data-testid=${this.browseButtonTestId}\n tabindex=\"-1\"\n variant=\"outline\"\n ?disabled=${this.disabled}\n size=${ifDefined(this.size) as CommonFormElementSize}\n @click=${this.onClick}\n @dragenter=${this.showDropzone ? nothing : this.onDragenter}\n @dragover=${this.showDropzone ? nothing : this.onDragover}\n @drop=${this.showDropzone ? nothing : this.onDrop}\n aria-label=\"${this.browseButtonLabel ||\n this.localize.t('fileInput.browse')}${this.showDropzone\n ? ''\n : ` - ${this.localize.t('fileInput.dragDropArea')}`}\"\n >${this.browseButtonLabel ||\n this.localize.t('fileInput.browse')}</dap-ds-button\n >`\n : nothing}\n ${this.showUploadButton === 'true' && !this.autoupload\n ? html`\n <dap-ds-button\n class=\"upload-button\"\n part=\"upload-button\"\n data-testid=${this.uploadButtonTestId}\n variant=\"primary\"\n size=${ifDefined(this.size) as CommonFormElementSize}\n ?disabled=${this._files.length === 0 ||\n !this.uploadUrl ||\n this._uploadingFiles.size > 0}\n @click=${this.startUpload}\n >${this.uploadButtonLabel ||\n this.localize.t('fileInput.upload')}</dap-ds-button\n >\n `\n : nothing}\n <div id=\"drop-instructions\" class=\"sr-only\">\n ${this.localize.t('fileInput.dragDropInstructions')}\n </div>\n </div>\n </span>\n ${!this.fileList && this._uploadingFiles.size > 0\n ? html`\n <div class=\"upload-progress\" part=\"upload-progress\">\n ${Array.from(this._uploadingFiles).map(fileName => {\n const progress = this._uploadProgress[fileName] || 0\n return html`\n <div class=\"upload-progress__item\">\n <dap-ds-typography variant=\"caption\">\n ${fileName} - ${Math.round(progress)}%\n </dap-ds-typography>\n <div class=\"upload-progress__bar\">\n <div\n class=\"upload-progress__fill\"\n style=\"width: ${progress}%\"></div>\n </div>\n </div>\n `\n })}\n </div>\n `\n : nothing}\n <dap-ds-modal\n .open=${this._showRemoveDialog}\n title=\"${this.localize.t('fileInput.removeDialog.title')}\"\n okButtonLabel=${this.removeButtonLabel ||\n this.localize.t('fileInput.removeDialog.confirm')}\n cancelButtonLabel=${this.cancelButtonLabel ||\n this.localize.t('fileInput.removeDialog.cancel')}\n .okButtonDanger=${this.removeButtonDanger === 'true'}\n @dds-cancel=${this.onCancelDelete}\n @dds-close=${this.onCancelDelete}\n @dds-ok=${this.onConfirmDelete}>\n <div>\n <dap-ds-typography variant=\"body\">\n ${this.localize.t('fileInput.removeDialog.message', {\n fileName: this._fileToRemove?.name ?? '',\n })}\n </dap-ds-typography>\n </div>\n </dap-ds-modal>\n\n ${this.feedback\n ? html`\n <dap-ds-feedback\n part=\"feedback\"\n feedbackType=${ifDefined(this.feedbackType)}\n feedbackSize=${ifDefined(this.size) as 'lg' | 'sm' | 'xs'}\n id=\"feedback\"\n .feedbackSubtle=${this.subtle}>\n ${this.feedback}\n </dap-ds-feedback>\n `\n : nothing}\n `\n }\n}\n"],"names":["_DapDSFileInput","GenericFormElement","file1","file2","file","type","acceptedType","baseType","fileList","errors","existingFileCount","t","totalSize","fileData","options","resolve","reject","__async","removedFiles","fileName","uploadResult","error","dataTransfer","i18next","event","customEvent","loading","fileComponent","xhr","newProgress","__spreadValues","HttpError","deleteEndpoint","headers","key","value","files","totalFiles","completedUploads","formData","__spreadProps","progress","response","result","fileError","FileError","_a","f","targetFiles","validation","fallbackFile","newFiles","allFiles","canceledFiles","acceptedFiles","droppedFiles","showBrowseButton","inputTabbable","html","formLabelTemplate","clsx","ifDefined","nothing","_b","DapDSFormLabel","DapDSTooltip","DapDSIconButton","DapDSIcon","DapDSTypography","DapDSButton","DapDSModal","DapDSFeedback","css","unsafeCSS","style","DapDSFileInput","__decorateClass","query","property","state"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- const e = "./_schema.json", n = { neutral: "Information", informative: "Information", positive: "Erfolg", warning: "Warnung", negative: "Fehler" }, t = "Schließen", i = "Abbrechen", a = "Auswahl löschen", r = "Kopieren", o = "Bestätigen", s = "Ok", c = "Suchen", l = "Tag", d = "(öffnet in neuem Tab)", h = { optional: "(Optional)", tooltip: "Information" }, g = { maxLength: "Maximale Länge um {{count}} Zeichen überschritten" }, u = { info: "Info", success: "Erfolg", error: "Fehler" }, m = { selected: "ausgewählt", disabled: "nicht verfügbar" }, b = "lädt", f = "Lädt...", p = "anzeigen", v = "ausblenden", D = "verringern", w = "erhöhen", S = "Inhaltsverzeichnis", z = "{{val, datetime}}", k = "ausgewählt", A = { today: "heute", now: "jetzt", nextMonth: "nächster Monat", prevMonth: "vorheriger Monat", year: "Jahr", month: "Monat" }, L = { validationMessage: { select: "Bitte wählen Sie eine Option", datepicker: "Bitte wählen Sie ein Datum" } }, x = { dragDropArea: "Dateien hier ablegen oder klicken zum Hochladen", dragDropInstructions: "Sie können Dateien auch durch Ziehen und Ablegen in den Bereich hochladen.", files: "Dateien", uploadButtonLabel: "Hochladen", browseButtonLabel: "Durchsuchen", browse: "Dateien durchsuchen", fileList: "Dateiliste", fileSize: "{{size}} MB", upload: "Hochladen", uploading: "Hochladen läuft", dropzone: { label: "Dateien hochladen", text: "Dateien hier ablegen oder klicken zum Hochladen", acceptedTypes: "Erlaubte Dateitypen" }, link: "Link", cancel: "Abbrechen", delete: "Löschen", view: "Ansehen", error: { fileSize: "Die Dateigröße überschreitet das maximale Limit von {size} MB", fileType: "Der Dateityp ist nicht erlaubt", fileAmount: "Die Anzahl der Dateien überschreitet das maximale Limit von {count}", perFileSize: "Die Dateigröße überschreitet das maximale Limit von {size} MB" }, removeDialog: { title: "Datei entfernen", message: "Sind Sie sicher, dass Sie {{fileName}} entfernen möchten?", confirm: "Löschen", cancel: "Abbrechen" } }, B = { pageSize: "{{count}} Einträge / Seite", first: "Erste", previous: "Zurück", next: "Weiter", last: "Letzte", pageInfo: "{{rangeStart}}-{{rangeEnd}} von {{totalRows}}" }, E = { sortAscending: "Aufsteigend sortieren", sortDescending: "Absteigend sortieren", clearSort: "Sortierung löschen", tableDescription: "Datentabelle mit sortierbaren Spalten", defaultCaption: "Datentabelle", rowSelected: "Zeile ausgewählt", rowDeselected: "Zeile abgewählt", sortedBy: "Sortiert nach {{column}} {{direction}}", pageChanged: "Seite {{page}} von {{total}}", noData: "Keine Daten verfügbar", resizeColumn: "Spaltenbreite ändern" }, M = { expand: "Abschnitt erweitern", collapse: "Abschnitt einklappen" }, I = { hour: "Stunde", minute: "Minute", second: "Sekunde" }, y = { remove: "Entfernen", removable: "entfernbar, drücken Sie Entf zum Entfernen" }, T = { notifications: "Benachrichtigungen" }, Z = { activeOption: "{{option}}, {{position}} von {{count}}", multiselect: { selected_one: "{{count}} Element ausgewählt", selected_other: "{{count}} Elemente ausgewählt" } }, H = { loading: "Lädt", progress: "Fortschritt: {{percentage}}%" }, O = {
1
+ const e = "./_schema.json", n = { neutral: "Information", informative: "Information", positive: "Erfolg", warning: "Warnung", negative: "Fehler" }, t = "Schließen", i = "Abbrechen", a = "Auswahl löschen", r = "Kopieren", o = "Bestätigen", s = "Ok", c = "Suchen", l = "Tag", d = "(öffnet in neuem Tab)", h = { optional: "(Optional)", tooltip: "Information" }, g = { maxLength: "Maximale Länge um {{count}} Zeichen überschritten" }, u = { info: "Info", success: "Erfolg", error: "Fehler" }, m = { selected: "ausgewählt", disabled: "nicht verfügbar" }, b = "lädt", p = "Lädt...", f = "anzeigen", v = "ausblenden", D = "verringern", w = "erhöhen", S = "Inhaltsverzeichnis", z = "{{val, datetime}}", k = "ausgewählt", A = { today: "heute", now: "jetzt", nextMonth: "nächster Monat", prevMonth: "vorheriger Monat", year: "Jahr", month: "Monat" }, B = { validationMessage: { select: "Bitte wählen Sie eine Option", datepicker: "Bitte wählen Sie ein Datum" } }, L = { dragDropArea: "Dateien hier ablegen oder klicken zum Hochladen", dragDropInstructions: "Sie können Dateien auch durch Ziehen und Ablegen in den Bereich hochladen.", uploadArea: "Datei-Upload-Bereich", files: "Dateien", uploadButtonLabel: "Hochladen", browseButtonLabel: "Durchsuchen", browse: "Dateien durchsuchen", fileList: "Dateiliste", fileSize: "{{size}} MB", upload: "Hochladen", uploading: "Hochladen läuft", dropzone: { label: "Dateien hochladen", text: "Dateien hier ablegen oder klicken zum Hochladen", acceptedTypes: "Erlaubte Dateitypen" }, link: "Link", cancel: "Abbrechen", delete: "Löschen", view: "Ansehen", error: { fileSize: "Die Dateigröße überschreitet das maximale Limit von {size} MB", fileType: "Der Dateityp ist nicht erlaubt", fileAmount: "Die Anzahl der Dateien überschreitet das maximale Limit von {count}", perFileSize: "Die Dateigröße überschreitet das maximale Limit von {size} MB" }, removeDialog: { title: "Datei entfernen", message: "Sind Sie sicher, dass Sie {{fileName}} entfernen möchten?", confirm: "Löschen", cancel: "Abbrechen" } }, x = { pageSize: "{{count}} Einträge / Seite", first: "Erste", previous: "Zurück", next: "Weiter", last: "Letzte", pageInfo: "{{rangeStart}}-{{rangeEnd}} von {{totalRows}}" }, E = { sortAscending: "Aufsteigend sortieren", sortDescending: "Absteigend sortieren", clearSort: "Sortierung löschen", tableDescription: "Datentabelle mit sortierbaren Spalten", defaultCaption: "Datentabelle", rowSelected: "Zeile ausgewählt", rowDeselected: "Zeile abgewählt", sortedBy: "Sortiert nach {{column}} {{direction}}", pageChanged: "Seite {{page}} von {{total}}", noData: "Keine Daten verfügbar", resizeColumn: "Spaltenbreite ändern" }, M = { expand: "Abschnitt erweitern", collapse: "Abschnitt einklappen" }, I = { hour: "Stunde", minute: "Minute", second: "Sekunde" }, y = { remove: "Entfernen", removable: "entfernbar, drücken Sie Entf zum Entfernen" }, T = { notifications: "Benachrichtigungen" }, Z = { activeOption: "{{option}}, {{position}} von {{count}}", multiselect: { selected_one: "{{count}} Element ausgewählt", selected_other: "{{count}} Elemente ausgewählt" } }, H = { loading: "Lädt", progress: "Fortschritt: {{percentage}}%" }, O = {
2
2
  $schema: e,
3
3
  bannerType: n,
4
4
  close: t,
@@ -18,8 +18,8 @@ const e = "./_schema.json", n = { neutral: "Information", informative: "Informat
18
18
  "dap-badge": "Erstellt im Rahmen des Programms für digitale Staatsbürgerschaft.",
19
19
  "dap-badge-large": "Der Service wurde im Rahmen des Programms für digitale Staatsbürgerschaft aktualisiert.",
20
20
  loading: b,
21
- spinner: f,
22
- show: p,
21
+ spinner: p,
22
+ show: f,
23
23
  hide: v,
24
24
  decrease: D,
25
25
  increase: w,
@@ -27,9 +27,9 @@ const e = "./_schema.json", n = { neutral: "Information", informative: "Informat
27
27
  date: z,
28
28
  selected: k,
29
29
  calendar: A,
30
- form: L,
31
- fileInput: x,
32
- pager: B,
30
+ form: B,
31
+ fileInput: L,
32
+ pager: x,
33
33
  datatable: E,
34
34
  accordion: M,
35
35
  "official-website-banner": { heading: "Die offizielle Website von Ungarn.", "heading-2": "Offizielle Regierungswebsite", content: "Nur offizielle Regierungswebsites mit der Endung gov.hu können verwendet werden, die gesetzlich geregelt sind und mehrere Schutzschichten haben." },
@@ -60,8 +60,8 @@ export {
60
60
  O as default,
61
61
  g as errors,
62
62
  u as feedback,
63
- x as fileInput,
64
- L as form,
63
+ L as fileInput,
64
+ B as form,
65
65
  v as hide,
66
66
  w as increase,
67
67
  h as label,
@@ -69,13 +69,13 @@ export {
69
69
  b as loading,
70
70
  s as ok,
71
71
  d as opensInNewTab,
72
- B as pager,
72
+ x as pager,
73
73
  H as progress,
74
74
  c as search,
75
75
  k as selected,
76
- p as show,
76
+ f as show,
77
77
  T as snackbar,
78
- f as spinner,
78
+ p as spinner,
79
79
  l as tag,
80
80
  I as timepicker,
81
81
  S as tocTitle
@@ -1,4 +1,4 @@
1
- const e = "./_schema.json", o = { neutral: "Information", informative: "Information", positive: "Success", warning: "Warning", negative: "Error" }, t = "Close", a = "Cancel", n = "Clear selection", i = "Copy", s = "Confirm", l = "Ok", c = "Search", r = "tag", d = "(opens in new tab)", p = { optional: "(Optional)", tooltip: "Information" }, m = { maxLength: "Exceeded the maximum length by {{count}} character" }, g = { info: "Info", success: "Success", error: "Error" }, f = { selected: "kiválasztva", disabled: "nem elérhető" }, u = "loading", h = "Loading...", b = "show", v = "hide", w = "decrease", x = "increase", y = "Table of contents", z = "{{val, datetime}}", D = "selected", k = { today: "today", now: "now", nextMonth: "next month", prevMonth: "previous month", year: "year", month: "month" }, C = { validationMessage: { select: "Please select an option", datepicker: "Please select a date" } }, S = { dragDropArea: "Drag and drop files here or click to upload", dragDropInstructions: "You can also upload files by dragging and dropping them into the area.", files: "Files", uploadButtonLabel: "Upload", browseButtonLabel: "Browse", browse: "Browse files", fileList: "File list", fileSize: "{{size}} MB", upload: "Upload", uploading: "Uploading", dropzone: { label: "Upload files", text: "Drag and drop files here or click to upload", acceptedTypes: "Accepted file types" }, link: "Link", cancel: "Cancel", delete: "Delete", view: "View", error: { fileSize: "The file size exceeds the maximum limit of {size} MB", fileType: "The file type is not allowed", fileAmount: "The number of files exceeds the maximum limit of {count}", perFileSize: "The file size exceeds the maximum limit of {size} MB" }, removeDialog: { title: "Remove file", message: "Are you sure you want to remove {{fileName}}?", confirm: "Delete", cancel: "Cancel" } }, T = { pageSize: "{{count}} items / page", first: "First", previous: "Previous", next: "Next", last: "Last", pageInfo: "{{rangeStart}}-{{rangeEnd}} of {{totalRows}}" }, B = { sortAscending: "Sort ascending", sortDescending: "Sort descending", clearSort: "Clear sort", tableDescription: "Data table with sortable columns", defaultCaption: "Data table", rowSelected: "Row selected", rowDeselected: "Row deselected", sortedBy: "Sorted by {{column}} {{direction}}", pageChanged: "Page {{page}} of {{total}}", noData: "No data available", resizeColumn: "Resize column" }, I = { expand: "Expand section", collapse: "Collapse section" }, L = { hour: "Hour", minute: "Minute", second: "Second" }, M = { remove: "Remove", removable: "removable, press Delete or Backspace to remove" }, P = { notifications: "Notifications" }, E = { activeOption: "{{option}}, {{position}} of {{count}}", multiselect: { selected_one: "{{count}} item selected", selected_other: "{{count}} items selected" } }, R = { loading: "Loading", progress: "Progress: {{percentage}}%" }, A = {
1
+ const e = "./_schema.json", o = { neutral: "Information", informative: "Information", positive: "Success", warning: "Warning", negative: "Error" }, t = "Close", a = "Cancel", n = "Clear selection", i = "Copy", s = "Confirm", l = "Ok", r = "Search", c = "tag", d = "(opens in new tab)", p = { optional: "(Optional)", tooltip: "Information" }, m = { maxLength: "Exceeded the maximum length by {{count}} character" }, g = { info: "Info", success: "Success", error: "Error" }, f = { selected: "kiválasztva", disabled: "nem elérhető" }, u = "loading", h = "Loading...", b = "show", v = "hide", w = "decrease", x = "increase", y = "Table of contents", z = "{{val, datetime}}", D = "selected", k = { today: "today", now: "now", nextMonth: "next month", prevMonth: "previous month", year: "year", month: "month" }, C = { validationMessage: { select: "Please select an option", datepicker: "Please select a date" } }, S = { dragDropArea: "Drag and drop files here or click to upload", dragDropInstructions: "You can also upload files by dragging and dropping them into the area.", uploadArea: "File upload area", files: "Files", uploadButtonLabel: "Upload", browseButtonLabel: "Browse", browse: "Browse files", fileList: "File list", fileSize: "{{size}} MB", upload: "Upload", uploading: "Uploading", dropzone: { label: "Upload files", text: "Drag and drop files here or click to upload", acceptedTypes: "Accepted file types" }, link: "Link", cancel: "Cancel", delete: "Delete", view: "View", error: { fileSize: "The file size exceeds the maximum limit of {size} MB", fileType: "The file type is not allowed", fileAmount: "The number of files exceeds the maximum limit of {count}", perFileSize: "The file size exceeds the maximum limit of {size} MB" }, removeDialog: { title: "Remove file", message: "Are you sure you want to remove {{fileName}}?", confirm: "Delete", cancel: "Cancel" } }, T = { pageSize: "{{count}} items / page", first: "First", previous: "Previous", next: "Next", last: "Last", pageInfo: "{{rangeStart}}-{{rangeEnd}} of {{totalRows}}" }, B = { sortAscending: "Sort ascending", sortDescending: "Sort descending", clearSort: "Clear sort", tableDescription: "Data table with sortable columns", defaultCaption: "Data table", rowSelected: "Row selected", rowDeselected: "Row deselected", sortedBy: "Sorted by {{column}} {{direction}}", pageChanged: "Page {{page}} of {{total}}", noData: "No data available", resizeColumn: "Resize column" }, I = { expand: "Expand section", collapse: "Collapse section" }, L = { hour: "Hour", minute: "Minute", second: "Second" }, M = { remove: "Remove", removable: "removable, press Delete or Backspace to remove" }, P = { notifications: "Notifications" }, A = { activeOption: "{{option}}, {{position}} of {{count}}", multiselect: { selected_one: "{{count}} item selected", selected_other: "{{count}} items selected" } }, E = { loading: "Loading", progress: "Progress: {{percentage}}%" }, R = {
2
2
  $schema: e,
3
3
  bannerType: o,
4
4
  close: t,
@@ -8,8 +8,8 @@ const e = "./_schema.json", o = { neutral: "Information", informative: "Informat
8
8
  copy: i,
9
9
  confirm: s,
10
10
  ok: l,
11
- search: c,
12
- tag: r,
11
+ search: r,
12
+ tag: c,
13
13
  opensInNewTab: d,
14
14
  label: p,
15
15
  errors: m,
@@ -37,8 +37,8 @@ const e = "./_schema.json", o = { neutral: "Information", informative: "Informat
37
37
  timepicker: L,
38
38
  chip: M,
39
39
  snackbar: P,
40
- combobox: E,
41
- progress: R,
40
+ combobox: A,
41
+ progress: E,
42
42
  "code-puncher": { slot: { "aria-label": "Digit {{index}} of {{count}}" } },
43
43
  "image-zoom": { expand: "Expand image", unzoom: "Minimize image" }
44
44
  };
@@ -51,13 +51,13 @@ export {
51
51
  M as chip,
52
52
  n as clear,
53
53
  t as close,
54
- E as combobox,
54
+ A as combobox,
55
55
  s as confirm,
56
56
  i as copy,
57
57
  B as datatable,
58
58
  z as date,
59
59
  w as decrease,
60
- A as default,
60
+ R as default,
61
61
  m as errors,
62
62
  g as feedback,
63
63
  S as fileInput,
@@ -70,13 +70,13 @@ export {
70
70
  l as ok,
71
71
  d as opensInNewTab,
72
72
  T as pager,
73
- R as progress,
74
- c as search,
73
+ E as progress,
74
+ r as search,
75
75
  D as selected,
76
76
  b as show,
77
77
  P as snackbar,
78
78
  h as spinner,
79
- r as tag,
79
+ c as tag,
80
80
  L as timepicker,
81
81
  y as tocTitle
82
82
  };
@@ -1,4 +1,4 @@
1
- const e = "./_schema.json", t = { neutral: "Információ", informative: "Információ", positive: "Sikeres", warning: "Figyelmeztetés", negative: "Hiba" }, a = "Bezár", l = "(új ablakban nyílik meg)", s = "címke", o = "Mégse", n = "Kiválasztás törlése", i = "Másolás", r = "Megerősít", c = "Ok", m = "Keresés", d = { optional: "(Nem kötelező)", tooltip: "Információ" }, g = { maxLength: "Túllépte {{count}} karakterrel a maximális hosszúságot" }, z = { info: "Tájékoztató", success: "Sikeres", error: "Hiba" }, k = { selected: "kiválasztva", disabled: "nem elérhető" }, p = "Betöltés", v = "mutat", b = "elrejt", f = "Csökkentés", h = "Növelés", u = "Tartalom", j = "{{val, datetime}}", y = "kiválasztva", M = { today: "mai nap", now: "most", nextMonth: "következő hónap", prevMonth: "előző hónap", year: "év", month: "hónap" }, w = { validationMessage: { select: "Kérem válasszon egy lehetőséget", datepicker: "Kérem válasszon egy dátumot" } }, x = { files: "Fájlok", dragDropArea: "Húzza ide a fájlokat vagy kattintson a feltöltésre", dragDropInstructions: "A fájlokat a területre húzva is feltöltheti.", uploadButtonLabel: "Feltöltés", browseButtonLabel: "Fájlok tallózása", browse: "Fájlok tallózása", fileList: "Fájl lista", upload: "Feltöltés", fileSize: "{{size}} MB", uploading: "Feltöltés folyamatban", dropzone: { label: "Fájlok feltöltése", text: "Húzza ide a fájlokat vagy kattintson a feltöltésre", acceptedTypes: "Megengedett fájl típusok" }, link: "Link", cancel: "Mégse", delete: "Törlés", view: "Megnézem", error: { fileSize: "A fájl mérete meghaladja a {{size}} MB maximális limitet", fileType: "A fájl típusa nem megengedett", fileAmount: "A fájlok száma meghaladja maximális limitet: {{count}}", perFileSize: "A fájl mérete meghaladja a {{size}} MB maximális limitet" }, removeDialog: { title: "Fájl törlése", message: "Biztosan törölni akarja a {{fileName}} fájlt?", confirm: "Törlés", cancel: "Mégse" } }, S = { pageSize: "{{count}} elem / oldal", first: "Első", previous: "Előző", next: "Következő", last: "Utolsó", pageInfo: "{{rangeStart}}-{{rangeEnd}} a {{totalRows}} elemből" }, A = { sortAscending: "Növekvő", sortDescending: "Csökkenő", clearSort: "Nincs rendezés", tableDescription: "Adattábla rendezhető oszlopokkal", defaultCaption: "Adattábla", rowSelected: "Sor kiválasztva", rowDeselected: "Sor kiválasztás törölve", sortedBy: "Rendezve {{column}} oszlop szerint {{direction}}", pageChanged: "{{page}}. oldal a {{total}} oldalból", noData: "Nincs elérhető adat", resizeColumn: "Oszlopszélesség módosítása" }, F = { expand: "Szakasz kibontása", collapse: "Szakasz összecsukása" }, B = { hour: "Óra", minute: "Perc", second: "Másodperc" }, T = { remove: "Eltávolítás", removable: "eltávolítható, nyomja meg a törlés billentyűt az eltávolításhoz" }, D = { activeOption: "{{option}}, {{count}} találatból {{position}}.", multiselect: { selected: "{{count}} elem kiválasztva" } }, I = { notifications: "Értesítések" }, K = { loading: "Betöltés", progress: "Folyamat: {{percentage}}%" }, N = {
1
+ const e = "./_schema.json", t = { neutral: "Információ", informative: "Információ", positive: "Sikeres", warning: "Figyelmeztetés", negative: "Hiba" }, a = "Bezár", l = "(új ablakban nyílik meg)", s = "címke", o = "Mégse", n = "Kiválasztás törlése", i = "Másolás", r = "Megerősít", c = "Ok", m = "Keresés", d = { optional: "(Nem kötelező)", tooltip: "Információ" }, g = { maxLength: "Túllépte {{count}} karakterrel a maximális hosszúságot" }, z = { info: "Tájékoztató", success: "Sikeres", error: "Hiba" }, k = { selected: "kiválasztva", disabled: "nem elérhető" }, p = "Betöltés", v = "mutat", b = "elrejt", f = "Csökkentés", u = "Növelés", h = "Tartalom", j = "{{val, datetime}}", y = "kiválasztva", M = { today: "mai nap", now: "most", nextMonth: "következő hónap", prevMonth: "előző hónap", year: "év", month: "hónap" }, w = { validationMessage: { select: "Kérem válasszon egy lehetőséget", datepicker: "Kérem válasszon egy dátumot" } }, x = { files: "Fájlok", dragDropArea: "Húzza ide a fájlokat vagy kattintson a feltöltésre", dragDropInstructions: "A fájlokat a területre húzva is feltöltheti.", uploadArea: "Fájlfeltöltési terület", uploadButtonLabel: "Feltöltés", browseButtonLabel: "Fájlok tallózása", browse: "Fájlok tallózása", fileList: "Fájl lista", upload: "Feltöltés", fileSize: "{{size}} MB", uploading: "Feltöltés folyamatban", dropzone: { label: "Fájlok feltöltése", text: "Húzza ide a fájlokat vagy kattintson a feltöltésre", acceptedTypes: "Megengedett fájl típusok" }, link: "Link", cancel: "Mégse", delete: "Törlés", view: "Megnézem", error: { fileSize: "A fájl mérete meghaladja a {{size}} MB maximális limitet", fileType: "A fájl típusa nem megengedett", fileAmount: "A fájlok száma meghaladja maximális limitet: {{count}}", perFileSize: "A fájl mérete meghaladja a {{size}} MB maximális limitet" }, removeDialog: { title: "Fájl törlése", message: "Biztosan törölni akarja a {{fileName}} fájlt?", confirm: "Törlés", cancel: "Mégse" } }, A = { pageSize: "{{count}} elem / oldal", first: "Első", previous: "Előző", next: "Következő", last: "Utolsó", pageInfo: "{{rangeStart}}-{{rangeEnd}} a {{totalRows}} elemből" }, F = { sortAscending: "Növekvő", sortDescending: "Csökkenő", clearSort: "Nincs rendezés", tableDescription: "Adattábla rendezhető oszlopokkal", defaultCaption: "Adattábla", rowSelected: "Sor kiválasztva", rowDeselected: "Sor kiválasztás törölve", sortedBy: "Rendezve {{column}} oszlop szerint {{direction}}", pageChanged: "{{page}}. oldal a {{total}} oldalból", noData: "Nincs elérhető adat", resizeColumn: "Oszlopszélesség módosítása" }, S = { expand: "Szakasz kibontása", collapse: "Szakasz összecsukása" }, B = { hour: "Óra", minute: "Perc", second: "Másodperc" }, T = { remove: "Eltávolítás", removable: "eltávolítható, nyomja meg a törlés billentyűt az eltávolításhoz" }, D = { activeOption: "{{option}}, {{count}} találatból {{position}}.", multiselect: { selected: "{{count}} elem kiválasztva" } }, I = { notifications: "Értesítések" }, K = { loading: "Betöltés", progress: "Folyamat: {{percentage}}%" }, N = {
2
2
  $schema: e,
3
3
  bannerType: t,
4
4
  close: a,
@@ -21,16 +21,16 @@ const e = "./_schema.json", t = { neutral: "Információ", informative: "Inform
21
21
  show: v,
22
22
  hide: b,
23
23
  decrease: f,
24
- increase: h,
25
- tocTitle: u,
24
+ increase: u,
25
+ tocTitle: h,
26
26
  date: j,
27
27
  selected: y,
28
28
  calendar: M,
29
29
  form: w,
30
30
  fileInput: x,
31
- pager: S,
32
- datatable: A,
33
- accordion: F,
31
+ pager: A,
32
+ datatable: F,
33
+ accordion: S,
34
34
  "official-website-banner": { heading: "Magyarország hivatalos weboldala.", "heading-2": "Hivatalos állami weboldal", content: "A gov.hu végződésű oldalakat csak hivatalos állami szervek használhatják, amik jogilag szabályzottak és több szintű védelemmel működnek." },
35
35
  "avatar-group": { "overflow-label": "{{count}} további kép" },
36
36
  timepicker: B,
@@ -43,7 +43,7 @@ const e = "./_schema.json", t = { neutral: "Információ", informative: "Inform
43
43
  };
44
44
  export {
45
45
  e as $schema,
46
- F as accordion,
46
+ S as accordion,
47
47
  t as bannerType,
48
48
  M as calendar,
49
49
  o as cancel,
@@ -53,7 +53,7 @@ export {
53
53
  D as combobox,
54
54
  r as confirm,
55
55
  i as copy,
56
- A as datatable,
56
+ F as datatable,
57
57
  j as date,
58
58
  f as decrease,
59
59
  N as default,
@@ -62,12 +62,12 @@ export {
62
62
  x as fileInput,
63
63
  w as form,
64
64
  b as hide,
65
- h as increase,
65
+ u as increase,
66
66
  d as label,
67
67
  k as listItems,
68
68
  c as ok,
69
69
  l as opensInNewTab,
70
- S as pager,
70
+ A as pager,
71
71
  K as progress,
72
72
  m as search,
73
73
  y as selected,
@@ -76,6 +76,6 @@ export {
76
76
  p as spinner,
77
77
  s as tag,
78
78
  B as timepicker,
79
- u as tocTitle
79
+ h as tocTitle
80
80
  };
81
81
  //# sourceMappingURL=hu.json.js.map