import * as i0 from '@angular/core';
import { input, booleanAttribute, computed, output, inject, ElementRef, Injector, signal, runInInjectionContext, effect, ChangeDetectionStrategy, Component } from '@angular/core';
import '@ui5/webcomponents/dist/FileUploader.js';
import * as i1 from '@fundamental-ngx/ui5-webcomponents/utils';
import { GenericControlValueAccessor } from '@fundamental-ngx/ui5-webcomponents/utils';

class FileUploader {
    constructor() {
        /**
         * Comma-separated list of file types that the component should accept.
      
      **Note:** Please make sure you are adding the `.` in front on the file type, e.g. `.png` in case you want to accept png's only.
         */
        this.accept = input(...(ngDevMode ? [undefined, { debugName: "accept" }] : []));
        /**
         * If set to "true", the input field of component will not be rendered. Only the default slot that is passed will be rendered.
      
      **Note:** Use this property in combination with the default slot to achieve a button-only file uploader design.
         */
        this.hideInput = input(false, ...(ngDevMode ? [{ debugName: "hideInput", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
        /**
         * Defines whether the component is in disabled state.
      
      **Note:** A disabled component is completely noninteractive.
         */
        this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
        /**
         * Allows multiple files to be chosen.
         */
        this.multiple = input(false, ...(ngDevMode ? [{ debugName: "multiple", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
        /**
         * Determines the name by which the component will be identified upon submission in an HTML form.
      
      **Note:** This property is only applicable within the context of an HTML Form element.
         */
        this.name = input(...(ngDevMode ? [undefined, { debugName: "name" }] : []));
        /**
         * Defines a short hint intended to aid the user with data entry when the component has no value.
         */
        this.placeholder = input(...(ngDevMode ? [undefined, { debugName: "placeholder" }] : []));
        /**
         * Defines the name/names of the file/files to upload.
         */
        this.value = input("", ...(ngDevMode ? [{ debugName: "value" }] : []));
        /**
         * Defines the maximum file size in megabytes which prevents the upload if at least one file exceeds it.
         */
        this.maxFileSize = input(...(ngDevMode ? [undefined, { debugName: "maxFileSize" }] : []));
        /**
         * Defines the value state of the component.
         */
        this.valueState = input("None", ...(ngDevMode ? [{ debugName: "valueState" }] : []));
        /**
         * Defines whether the component is required.
         */
        this.required = input(false, ...(ngDevMode ? [{ debugName: "required", transform: booleanAttribute }] : [{ transform: booleanAttribute }]));
        /**
         * Defines the accessible ARIA name of the component.
         */
        this.accessibleName = input(...(ngDevMode ? [undefined, { debugName: "accessibleName" }] : []));
        /**
         * Receives id(or many ids) of the elements that label the input.
         */
        this.accessibleNameRef = input(...(ngDevMode ? [undefined, { debugName: "accessibleNameRef" }] : []));
        /**
         * Defines the accessible description of the component.
         */
        this.accessibleDescription = input(...(ngDevMode ? [undefined, { debugName: "accessibleDescription" }] : []));
        /**
         * Receives id(or many ids) of the elements that describe the input.
         */
        this.accessibleDescriptionRef = input(...(ngDevMode ? [undefined, { debugName: "accessibleDescriptionRef" }] : [])); // className is now passed
        /**
         * FileList of all selected files.
         * @readonly This property is managed by the web component and updates reactively.
         * Based on schema: readonly field that updates via change event parameters.
         */
        this.files = computed(() => this._filesSignal(), ...(ngDevMode ? [{ debugName: "files" }] : []));
        /**
         * Event is fired when the value of the file path has been changed.
      
      **Note:** Keep in mind that because of the HTML input element of type file, the event is also fired in Chrome browser when the Cancel button of the uploads window is pressed.
         */
        this.ui5Change = output();
        /**
         * Event is fired when the size of a file is above the `maxFileSize` property value.
         */
        this.ui5FileSizeExceed = output();
        /**
         * Available slots for content projection in this component.
         *
         * Slots allow you to insert custom content into predefined areas of the web component.
         * Use the `slot` attribute on child elements to target specific slots.
         *
         * - **(default)**: This slot allows you to add custom content to the component, such as a button or any other interactive element to trigger the file selection dialog.
      
      **Note:** For best accessibility experience, set a `tabindex` of "-1" on your interactive element, or it will be set automatically.
      This slot is intended for use cases where you want a button-only file uploader.
      It is recommended to set `hideInput` property to "true" when using this slot.
      Not setting `hideInput` may negatively impact the screen reader users.
         * - **valueStateMessage**: Defines the value state message that will be displayed as pop up under the component.
      
      **Note:** If not specified, a default text (in the respective language) will be displayed.
      
      **Note:** The `valueStateMessage` would be displayed,
      when the component is in `Information`, `Critical` or `Negative` value state.
         *
         * @example
         * ```html
         * <ui5-file-uploader>
         *   <div slot="header">Custom header content</div>
         *   <p>Default slot content</p>
         * </ui5-file-uploader>
         * ```
         *
         * @readonly
         * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_templates_and_slots | MDN Web Components Slots}
         */
        this.slots = [
            {
                "name": "default",
                "description": "This slot allows you to add custom content to the component, such as a button or any other interactive element to trigger the file selection dialog.\n\n**Note:** For best accessibility experience, set a `tabindex` of \"-1\" on your interactive element, or it will be set automatically.\nThis slot is intended for use cases where you want a button-only file uploader.\nIt is recommended to set `hideInput` property to \"true\" when using this slot.\nNot setting `hideInput` may negatively impact the screen reader users."
            },
            {
                "name": "valueStateMessage",
                "description": "Defines the value state message that will be displayed as pop up under the component.\n\n**Note:** If not specified, a default text (in the respective language) will be displayed.\n\n**Note:** The `valueStateMessage` would be displayed,\nwhen the component is in `Information`, `Critical` or `Negative` value state.",
                "since": "1.0.0-rc.9"
            }
        ];
        this.elementRef = inject(ElementRef);
        this.injector = inject(Injector);
        // Internal signal to track files from change events
        this._filesSignal = signal(null, ...(ngDevMode ? [{ debugName: "_filesSignal" }] : []));
    }
    get element() {
        return this.elementRef.nativeElement;
    }
    ngAfterViewInit() {
        const wcElement = this.element;
        const inputsToSync = [
            'accept',
            'hideInput',
            'disabled',
            'multiple',
            'name',
            'placeholder',
            'value',
            'maxFileSize',
            'valueState',
            'required',
            'accessibleName',
            'accessibleNameRef',
            'accessibleDescription',
            'accessibleDescriptionRef',
        ];
        // Synchronize inputs (properties)
        for (const inputName of inputsToSync) {
            // Find the corresponding camelCase signal property on the Angular component
            const signalName = inputName.replace(/-./g, (x) => x[1].toUpperCase());
            // Use the Injector to run the effect in the correct context
            if (this[signalName] && typeof this[signalName] === 'function') {
                runInInjectionContext(this.injector, () => {
                    effect(() => {
                        // Read the signal value
                        const value = this[signalName]();
                        if (wcElement) {
                            // Write the value to the Web Component's property
                            wcElement[inputName] = value;
                        }
                    });
                });
            }
        }
        const outputsToSync = [
            'ui5Change',
            'ui5FileSizeExceed',
        ];
        // Synchronize outputs (events)
        for (const outputName of outputsToSync) {
            // Map Angular output name to UI5 web component event name
            const eventName = outputName.replace('ui5', '').replace(/([A-Z])/g, '-$1').toLowerCase().substring(1);
            // Ensure the output property exists and has an emit function before adding listener
            if (this[outputName] && typeof this[outputName].emit === 'function' && wcElement.addEventListener) {
                // Cast the listener to the correct type to satisfy TypeScript
                wcElement.addEventListener(eventName, (e) => {
                    // Update files signal when change event fires
                    if (eventName === 'change') {
                        const customEvent = e;
                        // Use files from event detail, fallback to web component property
                        const filesValue = customEvent.detail?.files || wcElement.files || null;
                        this._filesSignal.set(filesValue);
                    }
                    this[outputName].emit(e);
                });
            }
        }
        // Initialize files signal with current state using delayed initialization
        // to handle web component timing properly
        const initializeFiles = () => {
            const currentValue = wcElement.files || null;
            if (JSON.stringify(currentValue) !== JSON.stringify(this._filesSignal())) {
                this._filesSignal.set(currentValue);
            }
        };
        // Try immediate initialization
        initializeFiles();
        // Fallback delayed initialization if web component needs more time
        // Use requestAnimationFrame for zoneless compatibility
        requestAnimationFrame(() => initializeFiles());
    }
    static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FileUploader, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
    static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.4", type: FileUploader, isStandalone: true, selector: "ui5-file-uploader, [ui5-file-uploader]", inputs: { accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, hideInput: { classPropertyName: "hideInput", publicName: "hideInput", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, valueState: { classPropertyName: "valueState", publicName: "valueState", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, accessibleName: { classPropertyName: "accessibleName", publicName: "accessibleName", isSignal: true, isRequired: false, transformFunction: null }, accessibleNameRef: { classPropertyName: "accessibleNameRef", publicName: "accessibleNameRef", isSignal: true, isRequired: false, transformFunction: null }, accessibleDescription: { classPropertyName: "accessibleDescription", publicName: "accessibleDescription", isSignal: true, isRequired: false, transformFunction: null }, accessibleDescriptionRef: { classPropertyName: "accessibleDescriptionRef", publicName: "accessibleDescriptionRef", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { ui5Change: "ui5Change", ui5FileSizeExceed: "ui5FileSizeExceed" }, exportAs: ["ui5FileUploader"], hostDirectives: [{ directive: i1.GenericControlValueAccessor }], ngImport: i0, template: '<ng-content></ng-content>', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.4", ngImport: i0, type: FileUploader, decorators: [{
            type: Component,
            args: [{
                    standalone: true,
                    selector: 'ui5-file-uploader, [ui5-file-uploader]',
                    template: '<ng-content></ng-content>',
                    exportAs: 'ui5FileUploader',
                    hostDirectives: [GenericControlValueAccessor],
                    changeDetection: ChangeDetectionStrategy.OnPush,
                }]
        }] });

/**
 * Generated bundle index. Do not edit.
 */

export { FileUploader };
//# sourceMappingURL=fundamental-ngx-ui5-webcomponents-file-uploader.mjs.map
