@sixbell-telco/sdk
Version:
A collection of reusable components designed for use in Sixbell Telco Angular projects
1 lines • 48.1 kB
Source Map (JSON)
{"version":3,"file":"sixbell-telco-sdk-components-file-upload.mjs","sources":["../../../projects/sdk/components/file-upload/shared/const/file-upload.constants.ts","../../../projects/sdk/components/file-upload/file-dropzone/file-dropzone.component.ts","../../../projects/sdk/components/file-upload/file-dropzone/file-dropzone.component.html","../../../projects/sdk/components/file-upload/file-uploader/file-uploader.component.ts","../../../projects/sdk/components/file-upload/file-uploader/file-uploader.component.html","../../../projects/sdk/components/file-upload/sixbell-telco-sdk-components-file-upload.ts"],"sourcesContent":["export const AUDIO_EXTENSIONS = ['.mp3', '.wav', '.ogg', '.m4a', '.aac', '.wma'] as const;\nexport const VIDEO_EXTENSIONS = ['.mp4', '.avi', '.mov', '.wmv', '.mkv', '.flv', '.webm'] as const;\nexport const IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.svg', '.webp'] as const;\nexport const DOCUMENT_EXTENSIONS = ['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx', '.txt', '.csv'] as const;\nexport const ARCHIVE_EXTENSIONS = ['.zip', '.rar', '.7z'] as const;\nexport const CODE_EXTENSIONS = ['.html', '.xml', '.json', '.js', '.ts', '.css'] as const;\n","import { NgClass } from '@angular/common';\nimport { Component, computed, ElementRef, forwardRef, inject, input, model, output, signal, viewChild } from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { ControlValueAccessor, FormControl, FormGroup, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { _, TranslatePipe, TranslateService } from '@ngx-translate/core';\nimport { AudioPlayerComponent, AudioPlayerService, ButtonPlayComponent, Track } from '@sixbell-telco/sdk/components/audio-player';\nimport { ButtonComponent } from '@sixbell-telco/sdk/components/button';\nimport { IconComponent } from '@sixbell-telco/sdk/components/icon';\nimport {\n\tmatCloudUpload,\n\tmatDelete,\n\tmatDownload,\n\tmatError,\n\tmatInsertDriveFile,\n\tmatVisibility,\n\tmatVisibilityOff,\n} from '@sixbell-telco/sdk/components/icon/material/baseline';\nimport { TooltipComponent } from '@sixbell-telco/sdk/components/tooltip';\nimport { TypographyDirective } from '@sixbell-telco/sdk/directives/typography';\nimport { cn } from '@sixbell-telco/sdk/utils/cn';\nimport { ExtractExtensionPipe } from '@sixbell-telco/sdk/utils/pipes/extract-extension';\nimport { ToBytesPipe } from '@sixbell-telco/sdk/utils/pipes/to-bytes-extesion';\nimport { startWith, switchMap } from 'rxjs';\nimport { AUDIO_EXTENSIONS } from '../shared/const/file-upload.constants';\nimport { FileExtension } from '../shared/types/file-upload';\n\n/**\n * A customizable drag-and-drop file upload zone with audio playback capabilities\n *\n * @remarks\n * Supports file validation, multi-file uploads, and audio file preview/playback.\n * Implements ControlValueAccessor for Angular form integration.\n *\n * @example\n * ```html\n * <st-file-dropzone\n * [extensions]=\"['.mp3', '.wav']\"\n * [maxFiles]=\"3\"\n * (fileDropped)=\"handleUpload($event)\"\n * ></st-file-dropzone>\n * ```\n *\n * @example\n * ```html\n * <!-- Form integration -->\n * <st-file-dropzone\n * [parentForm]=\"mediaForm\"\n * formControlName=\"attachments\"\n * [multiple]=\"true\"\n * ></st-file-dropzone>\n * ```\n */\n@Component({\n\tselector: 'st-file-dropzone',\n\timports: [\n\t\tNgClass,\n\t\tButtonComponent,\n\t\tTypographyDirective,\n\t\tToBytesPipe,\n\t\tExtractExtensionPipe,\n\t\tIconComponent,\n\t\tButtonPlayComponent,\n\t\tAudioPlayerComponent,\n\t\tFormsModule,\n\t\tTranslatePipe,\n\t\tTooltipComponent,\n\t],\n\ttemplateUrl: './file-dropzone.component.html',\n\tproviders: [\n\t\t{\n\t\t\tprovide: NG_VALUE_ACCESSOR,\n\t\t\tuseExisting: forwardRef(() => DropzoneComponent),\n\t\t\tmulti: true,\n\t\t},\n\t],\n})\nexport class DropzoneComponent implements ControlValueAccessor {\n\t/** @internal Translation service instance */\n\ttranslateService = inject(TranslateService);\n\n\t/** @internal Audio player service instance */\n\taudioService = inject(AudioPlayerService);\n\n\t// Input properties\n\t/**\n\t * Maximum number of allowed files\n\t * @defaultValue 1\n\t */\n\tmaxFiles = input<number>(1);\n\n\t/**\n\t * Maximum file size in bytes (0 for unlimited)\n\t * @defaultValue 0\n\t */\n\tmaxFileSize = input<number>(0);\n\n\t/**\n\t * Whether to display uploaded files list\n\t * @defaultValue true\n\t */\n\tshowFiles = input<boolean>(true);\n\n\t/**\n\t * Allowed file extensions (e.g., ['.pdf', '.mp3'])\n\t */\n\textensions = input.required<FileExtension[]>();\n\n\t/**\n\t * Whether upload is in progress\n\t * @defaultValue false\n\t */\n\tuploading = input<boolean>(false);\n\n\t/**\n\t * Whether the component is disabled\n\t * @defaultValue false\n\t */\n\tdisabled = model<boolean>(false);\n\n\t/**\n\t * Whether multiple files can be uploaded\n\t * @defaultValue false\n\t */\n\tmultiple = input<boolean>(false);\n\n\t/**\n\t * HTML name attribute for the input\n\t * @defaultValue 'file'\n\t */\n\tname = input<string>('file');\n\n\t/**\n\t * Computed accept attribute for file input\n\t * @internal\n\t */\n\taccept = computed(() => this.extensions().join(','));\n\n\t/** @internal Tracks audio player open state */\n\topened = signal<boolean>(false);\n\n\t/** @internal Tracks blur events for validation */\n\tprivate blurTrigger = signal(0);\n\n\t// Form integration\n\t/**\n\t * Parent form group for reactive forms\n\t */\n\tparentForm = input<FormGroup | null>(null);\n\n\t/**\n\t * Form control name for reactive forms\n\t */\n\tformControlName = input<string>('');\n\n\t// Output events\n\t/**\n\t * Emitted when valid files are dropped/selected\n\t */\n\tfileDropped = output<File[]>();\n\n\t/**\n\t * Emitted when a file is removed\n\t */\n\tfileRemoved = output<File>();\n\n\t// Internal state\n\t/** @internal Current list of uploaded files */\n\tfiles = signal<File[]>([]);\n\n\t/** @internal Drag state tracker */\n\tisDragging = signal<boolean>(false);\n\n\t/** @internal Validation error message */\n\terrorMessage = signal<string>('');\n\n\t// ControlValueAccessor implementation\n\t/** @internal Change callback function */\n\tprivate onControlChange: (value: File[]) => void = () => {};\n\n\t/** @internal Touch callback function */\n\tprivate onControlTouch: () => void = () => {};\n\n\t/** @internal Reference to file input element */\n\tfileInput = viewChild<ElementRef>('fileInput');\n\n\t// Icon references\n\t/** @internal Material icon references */\n\ticonDelete = matDelete;\n\ticonDownload = matDownload;\n\ticonInsertDriveFile = matInsertDriveFile;\n\ticonCloudUpload = matCloudUpload;\n\ticonError = matError;\n\ticonVisibility = matVisibility;\n\ticonVisibilityOff = matVisibilityOff;\n\n\t/**\n\t * Computed audio tracks from uploaded files\n\t * @internal\n\t */\n\ttracks = computed<Track[]>(() => {\n\t\treturn this.files()\n\t\t\t.filter((audio) => this.checkIfIsAudioFile(audio))\n\t\t\t.map((audio) => ({\n\t\t\t\ttitle: audio.name,\n\t\t\t\tdescription: new ToBytesPipe().transform(audio.size),\n\t\t\t\turl: URL.createObjectURL(audio),\n\t\t\t}));\n\t});\n\n\t/**\n\t * Whether to show audio player controls\n\t * @internal\n\t */\n\taddAudioPlayer = computed(() => this.extensions().some((ext) => AUDIO_EXTENSIONS.includes(ext as (typeof AUDIO_EXTENSIONS)[number])));\n\n\t/**\n\t * Gets track index for audio files\n\t * @param file - File to check\n\t * @returns Index in audio tracks array\n\t * @internal\n\t */\n\tgetIndexForTracks(file: File) {\n\t\treturn this.files()\n\t\t\t.filter((audio) => this.checkIfIsAudioFile(audio))\n\t\t\t.indexOf(file);\n\t}\n\n\t// Drag and drop handlers\n\t/**\n\t * Handles drag over event\n\t * @param event - Drag event\n\t * @internal\n\t */\n\thandleDragOver(event: DragEvent) {\n\t\tevent.preventDefault();\n\t\tif (this.disabled()) return;\n\t\tthis.isDragging.set(true);\n\t}\n\n\t/**\n\t * Handles drag leave event\n\t * @param event - Drag event\n\t * @internal\n\t */\n\thandleDragLeave(event: DragEvent) {\n\t\tevent.preventDefault();\n\t\tthis.isDragging.set(false);\n\t}\n\n\t/**\n\t * Handles file drop event\n\t * @param event - Drag event\n\t * @internal\n\t */\n\thandleDrop(event: DragEvent) {\n\t\tevent.preventDefault();\n\t\tthis.isDragging.set(false);\n\t\tif (this.disabled()) return;\n\n\t\tconst files = Array.from(event.dataTransfer?.files || []);\n\t\tthis.processFiles(files);\n\t}\n\n\t/**\n\t * Handles file input selection\n\t * @param event - Input change event\n\t * @internal\n\t */\n\thandleFileSelect(event: Event) {\n\t\tconst input = event.target as HTMLInputElement;\n\t\tconst files = Array.from(input.files || []);\n\t\tthis.processFiles(files);\n\t\tinput.value = ''; // Reset input\n\t}\n\n\t/** @internal Processes and validates uploaded files */\n\tprivate processFiles(files: File[]) {\n\t\tthis.errorMessage.set('');\n\n\t\t// Validate max files\n\t\tconst totalFiles = this.files().length + files.length;\n\t\tif (this.maxFiles() > 0 && totalFiles > this.maxFiles()) {\n\t\t\tthis.translateService.get(_('sdk.fileUpload.dropzone.maxFilesExceeded'), { max: this.maxFiles() }).subscribe((res: string) => {\n\t\t\t\tthis.errorMessage.set(res);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\t// File validation\n\t\tconst validFiles = files.filter((file) => {\n\t\t\tconst isValidSize = this.validateFileSize(file);\n\t\t\tconst isValidType = this.validateFileType(file);\n\n\t\t\tif (!isValidSize) {\n\t\t\t\tconsole.warn(`File ${file.name} exceeds size limit`);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!isValidType) {\n\t\t\t\tconsole.warn(`File ${file.name} has invalid type`);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t\tif (validFiles.length > 0) {\n\t\t\tthis.files.update((current) => [...current, ...validFiles]);\n\t\t\tthis.onControlChange(this.files());\n\t\t\tthis.onControlTouch();\n\t\t\tthis.fileDropped.emit(validFiles);\n\t\t} else {\n\t\t\tthis.translateService.get(_('sdk.fileUpload.dropzone.noValidFiles')).subscribe((res: string) => {\n\t\t\t\tthis.errorMessage.set(res);\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Validates file size against maxFileSize\n\t * @param file - File to validate\n\t * @returns True if file size is valid\n\t * @internal\n\t */\n\tvalidateFileSize(file: File): boolean {\n\t\treturn this.maxFileSize() === 0 || file.size <= this.maxFileSize();\n\t}\n\n\t/**\n\t * Validates file type against allowed extensions\n\t * @param file - File to validate\n\t * @returns True if file type is valid\n\t * @internal\n\t */\n\tvalidateFileType(file: File): boolean {\n\t\tif (this.extensions().length === 0) return true;\n\t\tconst extension = file.name.match(/\\.([0-9a-z]+)$/i)?.[0]?.toLowerCase() || '';\n\t\treturn this.extensions().some((ext) => ext.toLowerCase() === extension);\n\t}\n\n\t/**\n\t * Handles file download\n\t * @param file - File to download\n\t * @internal\n\t */\n\thandlefileDownload(file: File) {\n\t\tconst url = URL.createObjectURL(file);\n\t\tconst a = document.createElement('a');\n\t\ta.href = url;\n\t\ta.download = file.name;\n\t\tdocument.body.appendChild(a);\n\t\ta.click();\n\t\tURL.revokeObjectURL(url);\n\t\tdocument.body.removeChild(a);\n\t}\n\n\t/**\n\t * Removes a file from the list\n\t * @param file - File to remove\n\t * @internal\n\t */\n\thandleRemove(file: File) {\n\t\tthis.files.update((current) => current.filter((f) => f !== file));\n\t\tthis.onControlChange(this.files());\n\t\tthis.onControlTouch();\n\t\tthis.fileRemoved.emit(file);\n\t}\n\n\t/**\n\t * Checks if a file is an audio file\n\t * @param file - File to check\n\t * @returns True if audio file\n\t * @internal\n\t */\n\tcheckIfIsAudioFile(file: File) {\n\t\treturn AUDIO_EXTENSIONS.some((ext) => file.name.endsWith(ext));\n\t}\n\n\t/**\n\t * Toggles audio player visibility\n\t * @internal\n\t */\n\thandleAudioPlayerOpen() {\n\t\tthis.opened.set(!this.opened());\n\t}\n\n\t/** @internal Cleans up object URLs */\n\tngDestroy() {\n\t\tthis.tracks().forEach((track) => URL.revokeObjectURL(track.url));\n\t}\n\n\t// ControlValueAccessor implementation\n\t/**\n\t * Writes form value to component\n\t * @param files - Array of files from form control\n\t */\n\twriteValue(files: File[]): void {\n\t\tthis.files.set(files || []);\n\t}\n\n\t/**\n\t * Registers change callback\n\t * @param fn - Callback function for value changes\n\t */\n\tregisterOnChange(fn: (value: File[]) => void): void {\n\t\tthis.onControlChange = fn;\n\t}\n\n\t/**\n\t * Registers touch callback\n\t * @param fn - Callback function for touch events\n\t */\n\tregisterOnTouched(fn: () => void): void {\n\t\tthis.onControlTouch = fn;\n\t}\n\n\t/**\n\t * Sets disabled state\n\t * @param isDisabled - Whether component is disabled\n\t */\n\tsetDisabledState(isDisabled: boolean): void {\n\t\tthis.disabled.set(isDisabled);\n\t}\n\n\t/**\n\t * Triggers file input dialog\n\t * @internal\n\t */\n\ttriggerFileInput() {\n\t\tif (!this.disabled()) {\n\t\t\tthis.fileInput()?.nativeElement.click();\n\t\t}\n\t}\n\n\t// Form control integration\n\t/** @internal Form control reference */\n\tprivate formControl = computed(() => this.parentForm()?.get(this.formControlName()) as FormControl | null);\n\n\t/** @internal Form control observable */\n\tprivate formControl$ = toObservable(this.formControl);\n\n\t/** @internal Status changes observable */\n\tprivate statusChanges$ = this.formControl$.pipe(switchMap((control) => control?.statusChanges.pipe(startWith(control.status)) || []));\n\n\t/** @internal Value changes observable */\n\tprivate stateChanges$ = this.formControl$.pipe(switchMap((control) => control?.valueChanges.pipe(startWith(control.value)) || []));\n\n\t/** @internal Status signal */\n\tprivate statusSignal = toSignal(this.statusChanges$);\n\n\t/** @internal State signal */\n\tprivate stateSignal = toSignal(this.stateChanges$);\n\n\t/**\n\t * Handles blur events for validation\n\t * @internal\n\t */\n\thandleBlur() {\n\t\tthis.onControlTouch();\n\t\tthis.blurTrigger.update((v) => v + 1);\n\t}\n\n\t/**\n\t * Computes CSS classes for dropzone based on state\n\t * @internal\n\t */\n\tdropzoneClass = computed(() => {\n\t\tconst control = this.formControl();\n\t\tconst trigger = this.blurTrigger();\n\n\t\tconst baseClasses =\n\t\t\t'cursor-pointer rounded-lg border-2 border-dashed p-8 text-center transition-colors duration-300 border-secondary hover:bg-secondary/10';\n\n\t\tif (!control) return baseClasses;\n\n\t\tconst isTouched = control.touched || trigger > 0;\n\t\tthis.statusSignal();\n\t\tthis.stateSignal();\n\n\t\tconst isFormError = control.invalid && (control.touched || isTouched);\n\t\tconst isComponentError = !!this.errorMessage();\n\n\t\treturn cn(baseClasses, {\n\t\t\t'border-secondary bg-secondary/30': this.isDragging() && !this.disabled(),\n\t\t\t'cursor-not-allowed bg-base-100/40 text-base-content/40': this.disabled(),\n\t\t\t'border-error bg-error/15 hover:border-error hover:bg-error/10': isComponentError || isFormError,\n\t\t});\n\t});\n}\n","<!-- eslint-disable @angular-eslint/template/click-events-have-key-events -->\n<div class=\"w-full\">\n\t<div\n\t\t[class]=\"dropzoneClass()\"\n\t\t(dragover)=\"handleDragOver($event)\"\n\t\t(dragleave)=\"handleDragLeave($event)\"\n\t\t(drop)=\"handleDrop($event)\"\n\t\t(click)=\"triggerFileInput()\"\n\t\t(blur)=\"handleBlur()\"\n\t\ttabindex=\"0\"\n\t>\n\t\t@if (parentForm()) {\n\t\t\t<input\n\t\t\t\t#fileInput\n\t\t\t\ttype=\"file\"\n\t\t\t\t[multiple]=\"multiple()\"\n\t\t\t\t[accept]=\"accept()\"\n\t\t\t\t(change)=\"handleFileSelect($event)\"\n\t\t\t\t[name]=\"name()\"\n\t\t\t\t(blur)=\"handleBlur()\"\n\t\t\t\trequired\n\t\t\t\thidden\n\t\t\t/>\n\t\t} @else {\n\t\t\t<input #fileInput type=\"file\" [multiple]=\"multiple()\" [accept]=\"accept()\" (change)=\"handleFileSelect($event)\" [name]=\"name()\" required hidden />\n\t\t}\n\n\t\t<div class=\"grid h-48 place-content-center\">\n\t\t\t@let errorMessageVar = this.errorMessage();\n\t\t\t@if (errorMessageVar) {\n\t\t\t\t<div>\n\t\t\t\t\t<st-icon [icon]=\"iconError\" size=\"xl\" class=\"text-error\" />\n\t\t\t\t\t<div typography [tyVariant]=\"'body'\">\n\t\t\t\t\t\t{{ errorMessageVar }}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t} @else if (!uploading()) {\n\t\t\t\t<div>\n\t\t\t\t\t<st-icon [icon]=\"iconCloudUpload\" size=\"xl\" class=\"text-accent\" />\n\t\t\t\t\t<div typography [tyVariant]=\"'body'\">\n\t\t\t\t\t\t{{ 'sdk.fileUpload.dropzone.selectPrompt' | translate }}\n\t\t\t\t\t</div>\n\n\t\t\t\t\t@if (maxFileSize() > 0) {\n\t\t\t\t\t\t<div class=\"mt-1\">\n\t\t\t\t\t\t\t<span typography [tyVariant]=\"'body-sm'\" tyFontWeight=\"medium\">\n\t\t\t\t\t\t\t\t{{ 'sdk.fileUpload.dropzone.maxSizeLabel' | translate }} <span class=\"text-accent\">{{ maxFileSize() | toBytes }}</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\n\t\t\t\t\t@if (extensions().length > 0) {\n\t\t\t\t\t\t<div class=\"mt-1\">\n\t\t\t\t\t\t\t<span typography [tyVariant]=\"'body-sm'\" tyFontWeight=\"medium\">\n\t\t\t\t\t\t\t\t{{ 'sdk.fileUpload.dropzone.allowedTypesLabel' | translate }} <span class=\"text-accent\">{{ extensions().join(', ') }}</span>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t}\n\t\t\t\t</div>\n\t\t\t}\n\t\t</div>\n\t</div>\n\n\t@if (maxFiles() > 0) {\n\t\t<div class=\"mt-4 flex items-center justify-between\">\n\t\t\t<ng-content></ng-content>\n\t\t\t<span typography [tyVariant]=\"'body-sm'\" [ngClass]=\"{ 'text-error': files().length > maxFiles() }\">\n\t\t\t\t{{ 'sdk.fileUpload.dropzone.fileCounter' | translate: { current: files().length, max: maxFiles() } }}\n\t\t\t</span>\n\t\t</div>\n\t}\n\n\t@if (showFiles() && files().length > 0) {\n\t\t<div class=\"mt-4 space-y-2\">\n\t\t\t@for (file of files(); track $index) {\n\t\t\t\t<div class=\"bg-neutral/30 flex items-center justify-between rounded-md py-3 pr-5 pl-3\">\n\t\t\t\t\t<div class=\"flex items-center justify-start\">\n\t\t\t\t\t\t<div class=\"text-primary relative\">\n\t\t\t\t\t\t\t<st-icon [icon]=\"iconInsertDriveFile\" size=\"xl\" />\n\t\t\t\t\t\t\t<div class=\"text-primary-content absolute bottom-2 left-1/2 -translate-x-1/2\">\n\t\t\t\t\t\t\t\t<span typography [tyVariant]=\"'body-xxs'\" tyFontWeight=\"medium\">\n\t\t\t\t\t\t\t\t\t{{ file.name | extractExtension }}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div class=\"flex flex-col items-start justify-between\">\n\t\t\t\t\t\t\t<span typography [tyVariant]=\"'body'\">\n\t\t\t\t\t\t\t\t{{ file.name }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t<div class=\"text-tertiary\">\n\t\t\t\t\t\t\t\t<span typography [tyVariant]=\"'body-xs'\"> {{ file.size | toBytes }} </span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"inline-flex items-center justify-end gap-1 align-top\">\n\t\t\t\t\t\t@if (checkIfIsAudioFile(file)) {\n\t\t\t\t\t\t\t<st-tooltip\n\t\t\t\t\t\t\t\t[label]=\"\n\t\t\t\t\t\t\t\t\t!this.audioService.isPlayingATrack()\n\t\t\t\t\t\t\t\t\t\t? ('sdk.fileUpload.dropzone.fileActions.play' | translate)\n\t\t\t\t\t\t\t\t\t\t: ('sdk.fileUpload.dropzone.fileActions.pause' | translate)\n\t\t\t\t\t\t\t\t\"\n\t\t\t\t\t\t\t\tvariant=\"secondary\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<st-button-play\n\t\t\t\t\t\t\t\t\t[outline]=\"true\"\n\t\t\t\t\t\t\t\t\t[square]=\"true\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t[asButton]=\"true\"\n\t\t\t\t\t\t\t\t\t[trackIndex]=\"getIndexForTracks(file)\"\n\t\t\t\t\t\t\t\t\t(togglePlay)=\"handleAudioPlayerOpen()\"\n\t\t\t\t\t\t\t\t></st-button-play>\n\t\t\t\t\t\t\t</st-tooltip>\n\t\t\t\t\t\t}\n\t\t\t\t\t\t<div></div>\n\t\t\t\t\t\t<st-tooltip [label]=\"'sdk.fileUpload.dropzone.fileActions.download' | translate\" variant=\"secondary\">\n\t\t\t\t\t\t\t<st-button variant=\"info\" [outline]=\"true\" [square]=\"true\" size=\"sm\" (click)=\"handlefileDownload(file)\">\n\t\t\t\t\t\t\t\t<st-icon class=\"text-lg\" [icon]=\"iconDownload\"></st-icon>\n\t\t\t\t\t\t\t</st-button>\n\t\t\t\t\t\t</st-tooltip>\n\t\t\t\t\t\t<st-tooltip [label]=\"'sdk.fileUpload.dropzone.fileActions.remove' | translate\" variant=\"secondary\">\n\t\t\t\t\t\t\t<st-button variant=\"error\" [outline]=\"true\" [square]=\"true\" size=\"sm\" (click)=\"handleRemove(file)\">\n\t\t\t\t\t\t\t\t<st-icon class=\"text-lg\" [icon]=\"iconDelete\"></st-icon>\n\t\t\t\t\t\t\t</st-button>\n\t\t\t\t\t\t</st-tooltip>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t}\n\t\t</div>\n\t}\n</div>\n@if (addAudioPlayer()) {\n\t<st-audio-player [tracks]=\"tracks()\" [showTrackList]=\"false\" variant=\"fixed\" [(opened)]=\"opened\"></st-audio-player>\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { ChangeDetectionStrategy, Component, computed, ElementRef, forwardRef, input, model, output, signal, viewChild } from '@angular/core';\nimport { toObservable, toSignal } from '@angular/core/rxjs-interop';\nimport { ControlValueAccessor, FormControl, FormGroup, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { TranslatePipe } from '@ngx-translate/core';\nimport { InputComponent, InputSizeProps, InputVariantProps } from '@sixbell-telco/sdk/components/forms/input';\nimport { TypographyDirective } from '@sixbell-telco/sdk/directives/typography';\nimport { startWith, switchMap } from 'rxjs';\nimport { FileExtension } from '../shared/types/file-upload';\n\n/** Possible style variants for the file uploader component */\nexport type FileUploaderVariantProps = InputVariantProps;\n\n/** Possible size variants for the file uploader component */\nexport type FileUploaderSizeProps = InputSizeProps;\n\n/** Configuration object for file uploader styling */\nexport type FileUploaderProps = {\n\tvariant?: FileUploaderVariantProps;\n\tsize?: FileUploaderSizeProps;\n};\n\n/**\n * A customizable file upload component with form integration and validation support\n *\n * @remarks\n * Supports file type restrictions, form control integration, and visual validation states.\n * Implements ControlValueAccessor for Angular form compatibility.\n *\n * @example\n * ```html\n * <!-- Basic file upload -->\n * <st-file-uploader\n * [extensions]=\"['.pdf', '.docx']\"\n * label=\"Upload Resume\"\n * ></st-file-uploader>\n * ```\n *\n * @example\n * ```html\n * <!-- Reactive form integration -->\n * <st-file-uploader\n * [parentForm]=\"documentForm\"\n * formControlName=\"attachment\"\n * variant=\"primary\"\n * ></st-file-uploader>\n * ```\n */\n@Component({\n\tselector: 'st-file-uploader',\n\timports: [FormsModule, InputComponent, TypographyDirective, TranslatePipe],\n\tproviders: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => FileUploaderComponent), multi: true }],\n\ttemplateUrl: './file-uploader.component.html',\n\tchangeDetection: ChangeDetectionStrategy.Default,\n})\nexport class FileUploaderComponent implements ControlValueAccessor {\n\t/**\n\t * Visual style variant\n\t * @defaultValue 'secondary'\n\t */\n\tvariant = input<FileUploaderVariantProps>('secondary');\n\n\t/**\n\t * Component size variant\n\t * @defaultValue 'md'\n\t */\n\tsize = input<FileUploaderSizeProps>('md');\n\n\t/**\n\t * Label displayed above the uploader\n\t */\n\tlabel = input<string>('');\n\n\t/**\n\t * HTML name attribute for the input\n\t */\n\tname = input<string | null>(null);\n\n\t/**\n\t * Placeholder text when no file is selected\n\t */\n\tplaceholder = input<string>('');\n\n\t/**\n\t * Whether to show allowed file extensions\n\t * @defaultValue true\n\t */\n\tshowExtensions = input<boolean>(true);\n\n\t/**\n\t * Allowed file extensions (e.g., ['.pdf', '.docx'])\n\t */\n\textensions = input.required<FileExtension[]>();\n\n\t/**\n\t * Computed accept attribute for native file input\n\t * @internal\n\t */\n\taccept = computed(() => this.extensions().join(','));\n\n\t/**\n\t * Event emitted when a valid file is selected\n\t */\n\tfileUpdated = output<File>();\n\n\t/**\n\t * Current selected filename\n\t * @internal\n\t */\n\tfilename = '';\n\n\t/**\n\t * Current file value\n\t * @internal\n\t */\n\tfileValue: File | null = null;\n\n\t/**\n\t * Formatted extensions string for display\n\t * @internal\n\t */\n\tformattedExtensions = computed(() => this.extensions().join(', '));\n\n\t/**\n\t * Reference to the hidden file input\n\t * @internal\n\t */\n\tfileInput = viewChild<ElementRef>('uploader');\n\n\t/**\n\t * Event emitted on component blur\n\t */\n\tblurred = output<File | null>();\n\n\t/**\n\t * Whether the component is disabled\n\t * @defaultValue false\n\t */\n\tdisabled = model<boolean>(false);\n\n\t/** @internal Track blur events for validation */\n\tprivate blurTrigger = signal(0);\n\n\t/**\n\t * Parent form group for reactive forms\n\t */\n\tparentForm = input<FormGroup | null>(null);\n\n\t/**\n\t * Form control name for reactive forms\n\t */\n\tformControlName = input<string>('');\n\n\t/**\n\t * Two-way bindable file value\n\t */\n\tvalue = model<File | null>(null);\n\n\t// ControlValueAccessor implementation\n\t/** @internal */\n\tprivate onControlChange: any = () => {};\n\t/** @internal */\n\tprivate onControlTouch: any = () => {};\n\n\t/**\n\t * Writes form value to component\n\t * @param obj - The incoming form value\n\t */\n\twriteValue(obj: any): void {\n\t\tthis.value.set(obj);\n\t}\n\n\t/**\n\t * Registers change callback\n\t * @param fn - Callback function for value changes\n\t */\n\tregisterOnChange(fn: any): void {\n\t\tthis.onControlChange = fn;\n\t}\n\n\t/**\n\t * Registers touch callback\n\t * @param fn - Callback function for touch events\n\t */\n\tregisterOnTouched(fn: any): void {\n\t\tthis.onControlTouch = fn;\n\t}\n\n\t/**\n\t * Sets disabled state\n\t * @param isDisabled - Whether the component should be disabled\n\t */\n\tsetDisabledState(isDisabled: boolean): void {\n\t\tthis.disabled.set(isDisabled);\n\t}\n\n\t/**\n\t * Handles click event on the upload area\n\t * @internal\n\t */\n\thandleClick() {\n\t\tif (!this.fileInput()) return;\n\t\tthis.fileInput()?.nativeElement.click();\n\t\tthis.handleBlur();\n\t}\n\n\t/**\n\t * Notifies form control of value changes\n\t * @internal\n\t */\n\thandleChange() {\n\t\tthis.onControlChange(this.value());\n\t}\n\n\t/**\n\t * Handles file selection from input\n\t * @param event - File input change event\n\t * @internal\n\t */\n\thandleFileChange(event: Event) {\n\t\tconst file: File | undefined = (event.target as HTMLInputElement).files?.[0];\n\t\tif (file instanceof File) {\n\t\t\tthis.filename = file.name;\n\t\t\tthis.value.set(file);\n\t\t\tthis.fileUpdated.emit(file);\n\t\t\tthis.handleChange();\n\t\t}\n\t}\n\n\t/**\n\t * Clears selected file\n\t * @internal\n\t */\n\tremoveFile() {\n\t\tthis.filename = '';\n\t\tthis.value.set(null);\n\t\tthis.handleChange();\n\t}\n\n\t/**\n\t * @internal\n\t * Returns base component classes\n\t */\n\tcomponentClass(): FileUploaderProps {\n\t\treturn {\n\t\t\tvariant: this.variant(),\n\t\t\tsize: this.size(),\n\t\t};\n\t}\n\n\t/**\n\t * @internal\n\t * Returns error state classes\n\t */\n\terrorClass(): FileUploaderProps {\n\t\treturn {\n\t\t\tvariant: 'error',\n\t\t\tsize: this.size(),\n\t\t};\n\t}\n\n\t/**\n\t * @internal\n\t * Returns success state classes\n\t */\n\tsuccessClass(): FileUploaderProps {\n\t\treturn {\n\t\t\tvariant: 'success',\n\t\t\tsize: this.size(),\n\t\t};\n\t}\n\n\t/**\n\t * Handles blur events and validation\n\t * @internal\n\t */\n\thandleBlur() {\n\t\tthis.blurred.emit(this.value());\n\t\tthis.onControlTouch();\n\t\tthis.blurTrigger.update((v) => v + 1);\n\t}\n\n\t// Form control integration\n\t/** @internal */\n\tprivate formControl = computed(() => this.parentForm()?.get(this.formControlName()) as FormControl | null);\n\t/** @internal */\n\tprivate formControl$ = toObservable(this.formControl);\n\t/** @internal */\n\tprivate statusChanges$ = this.formControl$.pipe(switchMap((control) => control?.statusChanges.pipe(startWith(control.status)) || []));\n\t/** @internal */\n\tprivate stateChanges$ = this.formControl$.pipe(switchMap((control) => control?.valueChanges.pipe(startWith(control.value)) || []));\n\t/** @internal */\n\tprivate statusSignal = toSignal(this.statusChanges$);\n\t/** @internal */\n\tprivate stateSignal = toSignal(this.stateChanges$);\n\n\t/**\n\t * Computes validation classes based on form state\n\t * @internal\n\t */\n\tvalidationClass = computed(() => {\n\t\tconst control = this.formControl();\n\t\tconst trigger = this.blurTrigger();\n\n\t\tif (!control) return this.componentClass();\n\n\t\tconst isTouched = control.touched || trigger > 0;\n\t\tthis.statusSignal();\n\t\tthis.stateSignal();\n\n\t\tif (control.dirty || isTouched) {\n\t\t\tif (control.invalid) return this.errorClass();\n\t\t\tif (control.valid) return this.successClass();\n\t\t}\n\n\t\treturn this.componentClass();\n\t});\n}\n","<st-input\n\t[label]=\"label()\"\n\t[placeholder]=\"placeholder()\"\n\t[readonly]=\"true\"\n\t(click)=\"handleClick()\"\n\t[(value)]=\"filename\"\n\t[name]=\"name()\"\n\t[variant]=\"validationClass().variant\"\n\t[size]=\"validationClass().size\"\n\t(blur)=\"handleBlur()\"\n\t[disabled]=\"disabled()\"\n\t(valueChange)=\"handleChange()\"\n>\n\t<div class=\"flex justify-between\">\n\t\t<div>\n\t\t\t<ng-content></ng-content>\n\t\t</div>\n\t\t@if (extensions().length > 0 && showExtensions()) {\n\t\t\t<div class=\"mt-1\">\n\t\t\t\t<span typography [tyVariant]=\"'body-xs'\" tyFontWeight=\"normal\">\n\t\t\t\t\t{{ 'sdk.fileUpload.fileUploader.allowedTypesLabel' | translate }} <span class=\"text-accent\">{{ formattedExtensions() }}</span>\n\t\t\t\t</span>\n\t\t\t</div>\n\t\t}\n\t</div>\n</st-input>\n\n<input type=\"file\" #uploader hidden (change)=\"handleFileChange($event)\" (blur)=\"handleBlur()\" [accept]=\"accept()\" required />\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}