mn-angular-lib 1.0.117 → 1.0.118
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.
|
@@ -2486,11 +2486,11 @@ class MnFileInput {
|
|
|
2486
2486
|
return segment || 'image';
|
|
2487
2487
|
}
|
|
2488
2488
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnFileInput, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2489
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnFileInput, isStandalone: true, selector: "mn-lib-file-input", inputs: { props: "props" }, outputs: { filesChange: "filesChange", cleared: "cleared" }, ngImport: i0, template: "<div [class.w-full]=\"props.fullWidth !== false && displayMode !== 'compact'\" class=\"flex flex-col\">\n <!-- Label -->\n @if (uiConfig.label) {\n <label [attr.for]=\"resolvedId\" class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\">\n <p>{{ uiConfig.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Hidden native file input shared by every trigger -->\n <input\n #fileInput\n (change)=\"onFileSelected($event)\"\n [accept]=\"acceptAttr\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || null\"\n [attr.multiple]=\"props.multiple || null\"\n [attr.name]=\"resolvedName\"\n [disabled]=\"isDisabled\"\n [id]=\"resolvedId\"\n class=\"hidden\"\n type=\"file\"\n />\n\n @switch (displayMode) {\n <!-- Compact: inline button + filename chips -->\n @case ('compact') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"inline-flex items-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @for (item of displayItems(); track itemKey(item)) {\n <span class=\"inline-flex items-center gap-1 text-sm text-base-content/70\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-6 w-6 rounded object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"max-w-40 truncate\">{{ item.name }}</span>\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </span>\n }\n </div>\n }\n\n <!-- List: compact rows of file icon + name + size -->\n @case ('list') {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"flex flex-row items-center justify-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-1\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-2 rounded-lg bg-base-200 px-3 py-1.5 text-sm\">\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n <span class=\"flex-1 truncate text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n\n <!-- Thumbnail: grid of tiles with overlay remove + add tile -->\n @case ('thumbnail') {\n <div class=\"flex flex-wrap gap-3\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"relative h-24 w-24 overflow-hidden rounded-xl border border-base-300 bg-base-100\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-full w-full object-cover\"/>\n } @else {\n <div class=\"flex h-full w-full flex-col items-center justify-center gap-1 p-1 text-center\">\n <svg lucideFile [size]=\"22\" class=\"text-base-content/50\"></svg>\n <span class=\"w-full truncate text-xs text-base-content/60\">{{ item.name }}</span>\n </div>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"
|
|
2489
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: MnFileInput, isStandalone: true, selector: "mn-lib-file-input", inputs: { props: "props" }, outputs: { filesChange: "filesChange", cleared: "cleared" }, ngImport: i0, template: "<div [class.w-full]=\"props.fullWidth !== false && displayMode !== 'compact'\" class=\"flex flex-col\">\n <!-- Label -->\n @if (uiConfig.label) {\n <label [attr.for]=\"resolvedId\" class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\">\n <p>{{ uiConfig.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Hidden native file input shared by every trigger -->\n <input\n #fileInput\n (change)=\"onFileSelected($event)\"\n [accept]=\"acceptAttr\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || null\"\n [attr.multiple]=\"props.multiple || null\"\n [attr.name]=\"resolvedName\"\n [disabled]=\"isDisabled\"\n [id]=\"resolvedId\"\n class=\"hidden\"\n type=\"file\"\n />\n\n @switch (displayMode) {\n <!-- Compact: inline button + filename chips -->\n @case ('compact') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"inline-flex items-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @for (item of displayItems(); track itemKey(item)) {\n <span class=\"inline-flex items-center gap-1 text-sm text-base-content/70\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-6 w-6 rounded object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"max-w-40 truncate\">{{ item.name }}</span>\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </span>\n }\n </div>\n }\n\n <!-- List: compact rows of file icon + name + size -->\n @case ('list') {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"flex flex-row items-center justify-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-1\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-2 rounded-lg bg-base-200 px-3 py-1.5 text-sm\">\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n <span class=\"flex-1 truncate text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n\n <!-- Thumbnail: grid of tiles with overlay remove + add tile -->\n @case ('thumbnail') {\n <div class=\"flex flex-wrap gap-3\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"relative h-24 w-24 overflow-hidden rounded-xl border border-base-300 bg-base-100\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-full w-full object-cover\"/>\n } @else {\n <div class=\"flex h-full w-full flex-col items-center justify-center gap-1 p-1 text-center\">\n <svg lucideFile [size]=\"22\" class=\"text-base-content/50\"></svg>\n <span class=\"w-full truncate text-xs text-base-content/60\">{{ item.name }}</span>\n </div>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"inline-flex h-6 w-6 items-center justify-center rounded-full cursor-pointer transition-colors absolute top-1 right-1 border-none bg-black/60 text-white hover:bg-black/80\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </div>\n }\n @if (props.multiple || displayItems().length === 0) {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n class=\"flex h-24 w-24 flex-col items-center justify-center gap-1 rounded-xl border-2 border-dashed border-base-300 text-base-content/50 hover:border-primary cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n type=\"button\">\n <svg lucideImagePlus [size]=\"22\"></svg>\n </button>\n }\n </div>\n }\n\n <!-- Dropzone (default): large dashed area + preview rows -->\n @default {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n type=\"button\">\n <svg lucideImagePlus [size]=\"28\" class=\"text-base-content/40\"></svg>\n <span class=\"text-sm text-base-content/60\">{{ uiConfig.dropzoneHint }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-2\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-3 rounded-lg bg-base-200 p-2\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-12 w-12 rounded-md object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"24\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"flex-1 truncate text-sm text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-sm text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"inline-flex h-8 w-8 items-center justify-center rounded-full cursor-pointer transition-colors hover:bg-base-200 text-base-content/60 hover:text-error\"\n type=\"button\">\n <svg lucideTrash2 [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n }\n\n <!-- Selection-limit error (accept / maxSize / maxFiles) -->\n @if (internalError(); as msg) {\n <mn-error-message [errorMessage]=\"msg\" [id]=\"resolvedId + '-selection'\"></mn-error-message>\n }\n\n <!-- Control validation errors -->\n @if (showError) {\n @if (props.showAllErrors) {\n <div class=\"flex flex-col gap-y-1\">\n @for (error of errorMessages; track $index) {\n <mn-error-message [errorMessage]=\"error\" [id]=\"resolvedId + '-' + $index\"></mn-error-message>\n }\n </div>\n } @else if (errorMessage !== null) {\n <mn-error-message [errorMessage]=\"errorMessage\" [id]=\"resolvedId\"></mn-error-message>\n }\n }\n</div>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: MnErrorMessage, selector: "mn-error-message", inputs: ["errorMessage", "id"] }, { kind: "component", type: LucideFile, selector: "svg[lucideFile]" }, { kind: "component", type: LucideImagePlus, selector: "svg[lucideImagePlus]" }, { kind: "component", type: LucideTrash2, selector: "svg[lucideTrash2]" }, { kind: "component", type: LucideUpload, selector: "svg[lucideUpload]" }, { kind: "component", type: LucideX, selector: "svg[lucideX]" }] });
|
|
2490
2490
|
}
|
|
2491
2491
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: MnFileInput, decorators: [{
|
|
2492
2492
|
type: Component,
|
|
2493
|
-
args: [{ selector: 'mn-lib-file-input', standalone: true, imports: [CommonModule, NgClass, MnErrorMessage, LucideFile, LucideImagePlus, LucideTrash2, LucideUpload, LucideX], template: "<div [class.w-full]=\"props.fullWidth !== false && displayMode !== 'compact'\" class=\"flex flex-col\">\n <!-- Label -->\n @if (uiConfig.label) {\n <label [attr.for]=\"resolvedId\" class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\">\n <p>{{ uiConfig.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Hidden native file input shared by every trigger -->\n <input\n #fileInput\n (change)=\"onFileSelected($event)\"\n [accept]=\"acceptAttr\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || null\"\n [attr.multiple]=\"props.multiple || null\"\n [attr.name]=\"resolvedName\"\n [disabled]=\"isDisabled\"\n [id]=\"resolvedId\"\n class=\"hidden\"\n type=\"file\"\n />\n\n @switch (displayMode) {\n <!-- Compact: inline button + filename chips -->\n @case ('compact') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"inline-flex items-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @for (item of displayItems(); track itemKey(item)) {\n <span class=\"inline-flex items-center gap-1 text-sm text-base-content/70\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-6 w-6 rounded object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"max-w-40 truncate\">{{ item.name }}</span>\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </span>\n }\n </div>\n }\n\n <!-- List: compact rows of file icon + name + size -->\n @case ('list') {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"flex flex-row items-center justify-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-1\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-2 rounded-lg bg-base-200 px-3 py-1.5 text-sm\">\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n <span class=\"flex-1 truncate text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n\n <!-- Thumbnail: grid of tiles with overlay remove + add tile -->\n @case ('thumbnail') {\n <div class=\"flex flex-wrap gap-3\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"relative h-24 w-24 overflow-hidden rounded-xl border border-base-300 bg-base-100\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-full w-full object-cover\"/>\n } @else {\n <div class=\"flex h-full w-full flex-col items-center justify-center gap-1 p-1 text-center\">\n <svg lucideFile [size]=\"22\" class=\"text-base-content/50\"></svg>\n <span class=\"w-full truncate text-xs text-base-content/60\">{{ item.name }}</span>\n </div>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"
|
|
2493
|
+
args: [{ selector: 'mn-lib-file-input', standalone: true, imports: [CommonModule, NgClass, MnErrorMessage, LucideFile, LucideImagePlus, LucideTrash2, LucideUpload, LucideX], template: "<div [class.w-full]=\"props.fullWidth !== false && displayMode !== 'compact'\" class=\"flex flex-col\">\n <!-- Label -->\n @if (uiConfig.label) {\n <label [attr.for]=\"resolvedId\" class=\"pl-2 pb-1 flex flex-row gap-x-0.5! text-base!\">\n <p>{{ uiConfig.label }}</p>\n @if (isRequired()) {\n <span class=\"text-red-500\">*</span>\n }\n </label>\n }\n\n <!-- Hidden native file input shared by every trigger -->\n <input\n #fileInput\n (change)=\"onFileSelected($event)\"\n [accept]=\"acceptAttr\"\n [attr.aria-label]=\"uiConfig.ariaLabel || uiConfig.label || null\"\n [attr.multiple]=\"props.multiple || null\"\n [attr.name]=\"resolvedName\"\n [disabled]=\"isDisabled\"\n [id]=\"resolvedId\"\n class=\"hidden\"\n type=\"file\"\n />\n\n @switch (displayMode) {\n <!-- Compact: inline button + filename chips -->\n @case ('compact') {\n <div class=\"flex flex-wrap items-center gap-2\">\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"inline-flex items-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @for (item of displayItems(); track itemKey(item)) {\n <span class=\"inline-flex items-center gap-1 text-sm text-base-content/70\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-6 w-6 rounded object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"max-w-40 truncate\">{{ item.name }}</span>\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </span>\n }\n </div>\n }\n\n <!-- List: compact rows of file icon + name + size -->\n @case ('list') {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n class=\"flex flex-row items-center justify-center gap-2 cursor-pointer hover:bg-base-200\"\n type=\"button\">\n <svg lucideUpload [size]=\"18\"></svg>\n <span class=\"text-sm\">{{ uiConfig.replaceLabel }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-1\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-2 rounded-lg bg-base-200 px-3 py-1.5 text-sm\">\n <svg lucideFile [size]=\"16\" class=\"text-base-content/50\"></svg>\n <span class=\"flex-1 truncate text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"text-base-content/50 hover:text-error cursor-pointer\"\n type=\"button\">\n <svg lucideX [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n\n <!-- Thumbnail: grid of tiles with overlay remove + add tile -->\n @case ('thumbnail') {\n <div class=\"flex flex-wrap gap-3\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"relative h-24 w-24 overflow-hidden rounded-xl border border-base-300 bg-base-100\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-full w-full object-cover\"/>\n } @else {\n <div class=\"flex h-full w-full flex-col items-center justify-center gap-1 p-1 text-center\">\n <svg lucideFile [size]=\"22\" class=\"text-base-content/50\"></svg>\n <span class=\"w-full truncate text-xs text-base-content/60\">{{ item.name }}</span>\n </div>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"inline-flex h-6 w-6 items-center justify-center rounded-full cursor-pointer transition-colors absolute top-1 right-1 border-none bg-black/60 text-white hover:bg-black/80\"\n type=\"button\">\n <svg lucideX [size]=\"14\"></svg>\n </button>\n </div>\n }\n @if (props.multiple || displayItems().length === 0) {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n class=\"flex h-24 w-24 flex-col items-center justify-center gap-1 rounded-xl border-2 border-dashed border-base-300 text-base-content/50 hover:border-primary cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed\"\n type=\"button\">\n <svg lucideImagePlus [size]=\"22\"></svg>\n </button>\n }\n </div>\n }\n\n <!-- Dropzone (default): large dashed area + preview rows -->\n @default {\n <button\n (click)=\"fileInput.click()\"\n [disabled]=\"isDisabled\"\n [ngClass]=\"controlClasses\"\n type=\"button\">\n <svg lucideImagePlus [size]=\"28\" class=\"text-base-content/40\"></svg>\n <span class=\"text-sm text-base-content/60\">{{ uiConfig.dropzoneHint }}</span>\n </button>\n @if (displayItems().length > 0) {\n <div class=\"mt-2 flex flex-col gap-2\">\n @for (item of displayItems(); track itemKey(item)) {\n <div class=\"flex items-center gap-3 rounded-lg bg-base-200 p-2\">\n @if (item.isImage && item.previewUrl) {\n <img [src]=\"item.previewUrl\" alt=\"\" class=\"h-12 w-12 rounded-md object-cover\"/>\n } @else {\n <svg lucideFile [size]=\"24\" class=\"text-base-content/50\"></svg>\n }\n <span class=\"flex-1 truncate text-sm text-base-content\">{{ item.name }}</span>\n @if (item.sizeLabel) {\n <span class=\"text-sm text-base-content/50\">{{ item.sizeLabel }}</span>\n }\n <button\n (click)=\"item.existing ? removeExisting(item.index) : removeFile(item.index)\"\n [attr.aria-label]=\"uiConfig.removeLabel\"\n class=\"inline-flex h-8 w-8 items-center justify-center rounded-full cursor-pointer transition-colors hover:bg-base-200 text-base-content/60 hover:text-error\"\n type=\"button\">\n <svg lucideTrash2 [size]=\"16\"></svg>\n </button>\n </div>\n }\n </div>\n }\n }\n }\n\n <!-- Selection-limit error (accept / maxSize / maxFiles) -->\n @if (internalError(); as msg) {\n <mn-error-message [errorMessage]=\"msg\" [id]=\"resolvedId + '-selection'\"></mn-error-message>\n }\n\n <!-- Control validation errors -->\n @if (showError) {\n @if (props.showAllErrors) {\n <div class=\"flex flex-col gap-y-1\">\n @for (error of errorMessages; track $index) {\n <mn-error-message [errorMessage]=\"error\" [id]=\"resolvedId + '-' + $index\"></mn-error-message>\n }\n </div>\n } @else if (errorMessage !== null) {\n <mn-error-message [errorMessage]=\"errorMessage\" [id]=\"resolvedId\"></mn-error-message>\n }\n }\n</div>\n" }]
|
|
2494
2494
|
}], ctorParameters: () => [], propDecorators: { props: [{
|
|
2495
2495
|
type: Input,
|
|
2496
2496
|
args: [{ required: true }]
|