@xui/upload 2.0.0-alpha.20 → 2.0.0-alpha.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/xui-upload.mjs +12 -0
- package/fesm2022/xui-upload.mjs.map +1 -1
- package/package.json +3 -3
- package/types/xui-upload.d.ts +12 -0
package/fesm2022/xui-upload.mjs
CHANGED
|
@@ -21,14 +21,26 @@ const [injectXuiUploadConfig, provideXuiUploadConfig] = createXConfigToken('XuiU
|
|
|
21
21
|
*/
|
|
22
22
|
class XuiUpload {
|
|
23
23
|
config = injectXuiUploadConfig();
|
|
24
|
+
/** Extra classes, merged into the component's own rather than replacing them. */
|
|
24
25
|
class = input('', /* @ts-ignore */
|
|
25
26
|
...(ngDevMode ? [{ debugName: "class" }] : /* istanbul ignore next */ []));
|
|
27
|
+
/** How files are chosen: a button that opens the picker, or a drop zone that also accepts a drag. */
|
|
26
28
|
type = input(this.config.type, /* @ts-ignore */
|
|
27
29
|
...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
30
|
+
/** Accept more than one file. With this off, a new choice replaces the current file rather than adding to it. */
|
|
28
31
|
multiple = input(false, { ...(ngDevMode ? { debugName: "multiple" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
32
|
+
/**
|
|
33
|
+
* Passed to the native input's `accept` — a comma-separated list of extensions or MIME types, and shown as a hint
|
|
34
|
+
* under a drop zone. A filter for the file chooser, not validation.
|
|
35
|
+
*/
|
|
29
36
|
accept = input('', /* @ts-ignore */
|
|
30
37
|
...(ngDevMode ? [{ debugName: "accept" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** Block choosing and dropping, and dim the control. */
|
|
31
39
|
disabled = input(false, { ...(ngDevMode ? { debugName: "disabled" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
40
|
+
/**
|
|
41
|
+
* The chosen files and their upload state. Two-way bindable — write back to it to report progress or mark a file as
|
|
42
|
+
* failed.
|
|
43
|
+
*/
|
|
32
44
|
files = model([], /* @ts-ignore */
|
|
33
45
|
...(ngDevMode ? [{ debugName: "files" }] : /* istanbul ignore next */ []));
|
|
34
46
|
/** The raw files just chosen (for the host to upload). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xui-upload.mjs","sources":["../../../../../../libs/ui/upload/xui/src/lib/upload.token.ts","../../../../../../libs/ui/upload/xui/src/lib/upload.ts","../../../../../../libs/ui/upload/xui/src/index.ts","../../../../../../libs/ui/upload/xui/src/xui-upload.ts"],"sourcesContent":["import { createXConfigToken } from '@xui/core';\nimport { XuiUploadType } from './upload';\n\nexport interface XuiUploadConfig {\n type: XuiUploadType;\n}\n\nexport const [injectXuiUploadConfig, provideXuiUploadConfig] = createXConfigToken<XuiUploadConfig>('XuiUploadConfig', {\n type: 'select'\n});\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n input,\n model,\n output,\n signal,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n matArrowUpwardRound,\n matCloseRound,\n matInsertDriveFileRound,\n matUploadRound\n} from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { injectXuiUploadConfig } from './upload.token';\n\nexport type XuiUploadStatus = 'uploading' | 'done' | 'error';\n\n/** How files are picked: a plain button or a drag-and-drop zone. */\nexport type XuiUploadType = 'select' | 'drag';\n\nexport interface XuiUploadFile {\n uid: string;\n name: string;\n size?: number;\n status?: XuiUploadStatus;\n /** Upload progress 0–100 (shown while `status` is `uploading`). */\n percent?: number;\n}\n\n/**\n * A file upload with a button or drag-and-drop zone and a file list showing\n * per-file progress, status and a remove control. `files` is a two-way bindable\n * list; `selected` emits the raw `File`s so the host can perform the upload and\n * update each file's `status`/`percent`.\n *\n * ```html\n * <xui-upload type=\"drag\" multiple [(files)]=\"files\" (selected)=\"upload($event)\" />\n * ```\n */\n@Component({\n selector: 'xui-upload',\n template: `\n <input\n #picker\n type=\"file\"\n class=\"hidden\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"accept() || null\"\n (change)=\"onPick($event)\"\n />\n\n @if (type() === 'drag') {\n <div\n [class]=\"dropzoneClass()\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"openPicker()\"\n (keydown.enter)=\"openPicker()\"\n (keydown.space)=\"openPicker(); $event.preventDefault()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"dragging.set(false)\"\n (drop)=\"onDrop($event)\"\n >\n <ng-icon xui size=\"lg\" color=\"muted\" name=\"matUploadRound\" class=\"mx-auto\" />\n <p class=\"text-foreground mt-2 text-sm\">Click or drag files here to upload</p>\n @if (accept()) {\n <p class=\"text-foreground-muted mt-1 text-xs\">Accepted: {{ accept() }}</p>\n }\n </div>\n } @else {\n <button type=\"button\" [class]=\"buttonClass()\" [disabled]=\"disabled()\" (click)=\"openPicker()\">\n <ng-icon xui size=\"sm\" name=\"matArrowUpwardRound\" />\n Upload\n </button>\n }\n\n @if (files().length) {\n <ul class=\"mt-2 flex flex-col gap-1\">\n @for (file of files(); track file.uid) {\n <li [class]=\"fileRowClass(file)\">\n <ng-icon xui size=\"sm\" name=\"matInsertDriveFileRound\" class=\"shrink-0\" />\n <span class=\"min-w-0 flex-1\">\n <span class=\"flex items-center gap-2\">\n <span class=\"truncate\">{{ file.name }}</span>\n @if (file.size !== undefined) {\n <span class=\"text-foreground-muted shrink-0 text-xs\">{{ formatSize(file.size) }}</span>\n }\n </span>\n @if (file.status === 'uploading') {\n <span class=\"bg-surface-inset mt-1 block h-1 w-full overflow-hidden rounded-full\">\n <span class=\"bg-primary block h-full transition-all\" [style.width.%]=\"file.percent ?? 0\"></span>\n </span>\n }\n </span>\n <button\n type=\"button\"\n class=\"text-foreground-muted hover:text-error shrink-0 cursor-pointer leading-none\"\n (click)=\"remove(file)\"\n [attr.aria-label]=\"'Remove ' + file.name\"\n >\n <ng-icon xui size=\"sm\" name=\"matCloseRound\" />\n </button>\n </li>\n }\n </ul>\n }\n `,\n host: {\n '[class]': 'computedClass()'\n },\n imports: [NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matArrowUpwardRound, matCloseRound, matInsertDriveFileRound, matUploadRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiUpload {\n private readonly config = injectXuiUploadConfig();\n\n readonly class = input<ClassValue>('');\n\n readonly type = input<XuiUploadType>(this.config.type);\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n readonly accept = input<string>('');\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n readonly files = model<XuiUploadFile[]>([]);\n /** The raw files just chosen (for the host to upload). */\n readonly selected = output<File[]>();\n\n private readonly picker = viewChild.required<ElementRef<HTMLInputElement>>('picker');\n protected readonly dragging = signal(false);\n private uidCounter = 0;\n\n protected openPicker(): void {\n if (!this.disabled()) {\n this.picker().nativeElement.click();\n }\n }\n\n protected onPick(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.addFiles(input.files);\n input.value = '';\n }\n\n protected onDragOver(event: DragEvent): void {\n if (this.disabled()) {\n return;\n }\n event.preventDefault();\n this.dragging.set(true);\n }\n\n protected onDrop(event: DragEvent): void {\n if (this.disabled()) {\n return;\n }\n event.preventDefault();\n this.dragging.set(false);\n this.addFiles(event.dataTransfer?.files ?? null);\n }\n\n private addFiles(fileList: FileList | null): void {\n if (!fileList || fileList.length === 0) {\n return;\n }\n const raw = Array.from(fileList);\n const chosen = this.multiple() ? raw : raw.slice(0, 1);\n const entries: XuiUploadFile[] = chosen.map(file => ({\n uid: `f-${++this.uidCounter}`,\n name: file.name,\n size: file.size,\n status: 'done'\n }));\n this.files.set(this.multiple() ? [...this.files(), ...entries] : entries);\n this.selected.emit(chosen);\n }\n\n protected remove(file: XuiUploadFile): void {\n this.files.set(this.files().filter(f => f.uid !== file.uid));\n }\n\n protected formatSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = ['KB', 'MB', 'GB'];\n let size = bytes / 1024;\n let unit = 0;\n while (size >= 1024 && unit < units.length - 1) {\n size /= 1024;\n unit++;\n }\n return `${size.toFixed(1)} ${units[unit]}`;\n }\n\n protected readonly computedClass = computed(() => xui('block', this.class()));\n protected readonly buttonClass = computed(() =>\n xui(\n 'border-border text-foreground hover:bg-surface-inset inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm disabled:opacity-50'\n )\n );\n protected readonly dropzoneClass = computed(() =>\n xui(\n 'cursor-pointer rounded-lg border-2 border-dashed px-6 py-8 text-center transition-colors',\n this.dragging() ? 'border-primary bg-primary/5' : 'border-border hover:border-primary/60',\n this.disabled() && 'pointer-events-none opacity-50'\n )\n );\n\n protected fileRowClass(file: XuiUploadFile): string {\n return xui(\n 'bg-surface flex items-center gap-2 rounded-md px-2 py-1.5 text-sm',\n file.status === 'error' ? 'text-error' : 'text-foreground'\n );\n }\n}\n","import { XuiUpload } from './lib/upload';\n\nexport * from './lib/upload';\nexport * from './lib/upload.token';\n\nexport const XuiUploadImports = [XuiUpload] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"xui-upload.mjs","sources":["../../../../../../libs/ui/upload/xui/src/lib/upload.token.ts","../../../../../../libs/ui/upload/xui/src/lib/upload.ts","../../../../../../libs/ui/upload/xui/src/index.ts","../../../../../../libs/ui/upload/xui/src/xui-upload.ts"],"sourcesContent":["import { createXConfigToken } from '@xui/core';\nimport { XuiUploadType } from './upload';\n\nexport interface XuiUploadConfig {\n type: XuiUploadType;\n}\n\nexport const [injectXuiUploadConfig, provideXuiUploadConfig] = createXConfigToken<XuiUploadConfig>('XuiUploadConfig', {\n type: 'select'\n});\n","import { BooleanInput } from '@angular/cdk/coercion';\nimport {\n booleanAttribute,\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n input,\n model,\n output,\n signal,\n viewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { NgIcon, provideIcons } from '@ng-icons/core';\nimport {\n matArrowUpwardRound,\n matCloseRound,\n matInsertDriveFileRound,\n matUploadRound\n} from '@ng-icons/material-icons/round';\nimport { xui } from '@xui/core';\nimport { XuiIcon } from '@xui/icon';\nimport type { ClassValue } from 'clsx';\nimport { injectXuiUploadConfig } from './upload.token';\n\nexport type XuiUploadStatus = 'uploading' | 'done' | 'error';\n\n/** How files are picked: a plain button or a drag-and-drop zone. */\nexport type XuiUploadType = 'select' | 'drag';\n\nexport interface XuiUploadFile {\n uid: string;\n name: string;\n size?: number;\n status?: XuiUploadStatus;\n /** Upload progress 0–100 (shown while `status` is `uploading`). */\n percent?: number;\n}\n\n/**\n * A file upload with a button or drag-and-drop zone and a file list showing\n * per-file progress, status and a remove control. `files` is a two-way bindable\n * list; `selected` emits the raw `File`s so the host can perform the upload and\n * update each file's `status`/`percent`.\n *\n * ```html\n * <xui-upload type=\"drag\" multiple [(files)]=\"files\" (selected)=\"upload($event)\" />\n * ```\n */\n@Component({\n selector: 'xui-upload',\n template: `\n <input\n #picker\n type=\"file\"\n class=\"hidden\"\n [multiple]=\"multiple()\"\n [attr.accept]=\"accept() || null\"\n (change)=\"onPick($event)\"\n />\n\n @if (type() === 'drag') {\n <div\n [class]=\"dropzoneClass()\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"openPicker()\"\n (keydown.enter)=\"openPicker()\"\n (keydown.space)=\"openPicker(); $event.preventDefault()\"\n (dragover)=\"onDragOver($event)\"\n (dragleave)=\"dragging.set(false)\"\n (drop)=\"onDrop($event)\"\n >\n <ng-icon xui size=\"lg\" color=\"muted\" name=\"matUploadRound\" class=\"mx-auto\" />\n <p class=\"text-foreground mt-2 text-sm\">Click or drag files here to upload</p>\n @if (accept()) {\n <p class=\"text-foreground-muted mt-1 text-xs\">Accepted: {{ accept() }}</p>\n }\n </div>\n } @else {\n <button type=\"button\" [class]=\"buttonClass()\" [disabled]=\"disabled()\" (click)=\"openPicker()\">\n <ng-icon xui size=\"sm\" name=\"matArrowUpwardRound\" />\n Upload\n </button>\n }\n\n @if (files().length) {\n <ul class=\"mt-2 flex flex-col gap-1\">\n @for (file of files(); track file.uid) {\n <li [class]=\"fileRowClass(file)\">\n <ng-icon xui size=\"sm\" name=\"matInsertDriveFileRound\" class=\"shrink-0\" />\n <span class=\"min-w-0 flex-1\">\n <span class=\"flex items-center gap-2\">\n <span class=\"truncate\">{{ file.name }}</span>\n @if (file.size !== undefined) {\n <span class=\"text-foreground-muted shrink-0 text-xs\">{{ formatSize(file.size) }}</span>\n }\n </span>\n @if (file.status === 'uploading') {\n <span class=\"bg-surface-inset mt-1 block h-1 w-full overflow-hidden rounded-full\">\n <span class=\"bg-primary block h-full transition-all\" [style.width.%]=\"file.percent ?? 0\"></span>\n </span>\n }\n </span>\n <button\n type=\"button\"\n class=\"text-foreground-muted hover:text-error shrink-0 cursor-pointer leading-none\"\n (click)=\"remove(file)\"\n [attr.aria-label]=\"'Remove ' + file.name\"\n >\n <ng-icon xui size=\"sm\" name=\"matCloseRound\" />\n </button>\n </li>\n }\n </ul>\n }\n `,\n host: {\n '[class]': 'computedClass()'\n },\n imports: [NgIcon, XuiIcon],\n viewProviders: [provideIcons({ matArrowUpwardRound, matCloseRound, matInsertDriveFileRound, matUploadRound })],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n})\nexport class XuiUpload {\n private readonly config = injectXuiUploadConfig();\n\n /** Extra classes, merged into the component's own rather than replacing them. */\n readonly class = input<ClassValue>('');\n\n /** How files are chosen: a button that opens the picker, or a drop zone that also accepts a drag. */\n readonly type = input<XuiUploadType>(this.config.type);\n /** Accept more than one file. With this off, a new choice replaces the current file rather than adding to it. */\n readonly multiple = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n /**\n * Passed to the native input's `accept` — a comma-separated list of extensions or MIME types, and shown as a hint\n * under a drop zone. A filter for the file chooser, not validation.\n */\n readonly accept = input<string>('');\n /** Block choosing and dropping, and dim the control. */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * The chosen files and their upload state. Two-way bindable — write back to it to report progress or mark a file as\n * failed.\n */\n readonly files = model<XuiUploadFile[]>([]);\n /** The raw files just chosen (for the host to upload). */\n readonly selected = output<File[]>();\n\n private readonly picker = viewChild.required<ElementRef<HTMLInputElement>>('picker');\n protected readonly dragging = signal(false);\n private uidCounter = 0;\n\n protected openPicker(): void {\n if (!this.disabled()) {\n this.picker().nativeElement.click();\n }\n }\n\n protected onPick(event: Event): void {\n const input = event.target as HTMLInputElement;\n this.addFiles(input.files);\n input.value = '';\n }\n\n protected onDragOver(event: DragEvent): void {\n if (this.disabled()) {\n return;\n }\n event.preventDefault();\n this.dragging.set(true);\n }\n\n protected onDrop(event: DragEvent): void {\n if (this.disabled()) {\n return;\n }\n event.preventDefault();\n this.dragging.set(false);\n this.addFiles(event.dataTransfer?.files ?? null);\n }\n\n private addFiles(fileList: FileList | null): void {\n if (!fileList || fileList.length === 0) {\n return;\n }\n const raw = Array.from(fileList);\n const chosen = this.multiple() ? raw : raw.slice(0, 1);\n const entries: XuiUploadFile[] = chosen.map(file => ({\n uid: `f-${++this.uidCounter}`,\n name: file.name,\n size: file.size,\n status: 'done'\n }));\n this.files.set(this.multiple() ? [...this.files(), ...entries] : entries);\n this.selected.emit(chosen);\n }\n\n protected remove(file: XuiUploadFile): void {\n this.files.set(this.files().filter(f => f.uid !== file.uid));\n }\n\n protected formatSize(bytes: number): string {\n if (bytes < 1024) {\n return `${bytes} B`;\n }\n const units = ['KB', 'MB', 'GB'];\n let size = bytes / 1024;\n let unit = 0;\n while (size >= 1024 && unit < units.length - 1) {\n size /= 1024;\n unit++;\n }\n return `${size.toFixed(1)} ${units[unit]}`;\n }\n\n protected readonly computedClass = computed(() => xui('block', this.class()));\n protected readonly buttonClass = computed(() =>\n xui(\n 'border-border text-foreground hover:bg-surface-inset inline-flex items-center gap-2 rounded-md border px-3 py-1.5 text-sm disabled:opacity-50'\n )\n );\n protected readonly dropzoneClass = computed(() =>\n xui(\n 'cursor-pointer rounded-lg border-2 border-dashed px-6 py-8 text-center transition-colors',\n this.dragging() ? 'border-primary bg-primary/5' : 'border-border hover:border-primary/60',\n this.disabled() && 'pointer-events-none opacity-50'\n )\n );\n\n protected fileRowClass(file: XuiUploadFile): string {\n return xui(\n 'bg-surface flex items-center gap-2 rounded-md px-2 py-1.5 text-sm',\n file.status === 'error' ? 'text-error' : 'text-foreground'\n );\n }\n}\n","import { XuiUpload } from './lib/upload';\n\nexport * from './lib/upload';\nexport * from './lib/upload.token';\n\nexport const XuiUploadImports = [XuiUpload] as const;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xui/upload",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.22",
|
|
4
4
|
"description": "Modern Angular 22 UI Library based on TailwindCSS",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"@angular/core": "22",
|
|
41
41
|
"@ng-icons/core": "34",
|
|
42
42
|
"@ng-icons/material-icons": "34",
|
|
43
|
-
"@xui/core": "2.0.0-alpha.
|
|
44
|
-
"@xui/icon": "2.0.0-alpha.
|
|
43
|
+
"@xui/core": "2.0.0-alpha.22",
|
|
44
|
+
"@xui/icon": "2.0.0-alpha.22",
|
|
45
45
|
"clsx": "^2.1.1"
|
|
46
46
|
},
|
|
47
47
|
"publishConfig": {
|
package/types/xui-upload.d.ts
CHANGED
|
@@ -25,11 +25,23 @@ interface XuiUploadFile {
|
|
|
25
25
|
*/
|
|
26
26
|
declare class XuiUpload {
|
|
27
27
|
private readonly config;
|
|
28
|
+
/** Extra classes, merged into the component's own rather than replacing them. */
|
|
28
29
|
readonly class: _angular_core.InputSignal<ClassValue>;
|
|
30
|
+
/** How files are chosen: a button that opens the picker, or a drop zone that also accepts a drag. */
|
|
29
31
|
readonly type: _angular_core.InputSignal<XuiUploadType>;
|
|
32
|
+
/** Accept more than one file. With this off, a new choice replaces the current file rather than adding to it. */
|
|
30
33
|
readonly multiple: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
|
|
34
|
+
/**
|
|
35
|
+
* Passed to the native input's `accept` — a comma-separated list of extensions or MIME types, and shown as a hint
|
|
36
|
+
* under a drop zone. A filter for the file chooser, not validation.
|
|
37
|
+
*/
|
|
31
38
|
readonly accept: _angular_core.InputSignal<string>;
|
|
39
|
+
/** Block choosing and dropping, and dim the control. */
|
|
32
40
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, BooleanInput>;
|
|
41
|
+
/**
|
|
42
|
+
* The chosen files and their upload state. Two-way bindable — write back to it to report progress or mark a file as
|
|
43
|
+
* failed.
|
|
44
|
+
*/
|
|
33
45
|
readonly files: _angular_core.ModelSignal<XuiUploadFile[]>;
|
|
34
46
|
/** The raw files just chosen (for the host to upload). */
|
|
35
47
|
readonly selected: _angular_core.OutputEmitterRef<File[]>;
|