@tekus/design-system 5.34.0 → 5.36.0
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/tekus-design-system-components-action-group.mjs +1 -1
- package/fesm2022/tekus-design-system-components-action-group.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-button.mjs +24 -3
- package/fesm2022/tekus-design-system-components-button.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-card.mjs +1 -1
- package/fesm2022/tekus-design-system-components-card.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-carousel.mjs +234 -0
- package/fesm2022/tekus-design-system-components-carousel.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-color-picker.mjs +1 -1
- package/fesm2022/tekus-design-system-components-color-picker.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-drawer.mjs +1 -1
- package/fesm2022/tekus-design-system-components-drawer.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-dropdown.mjs +1 -1
- package/fesm2022/tekus-design-system-components-dropdown.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs +1 -1
- package/fesm2022/tekus-design-system-components-fallback-view.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-header.mjs +29 -0
- package/fesm2022/tekus-design-system-components-header.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-icon.mjs +2 -2
- package/fesm2022/tekus-design-system-components-icon.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-modal.mjs +51 -31
- package/fesm2022/tekus-design-system-components-modal.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-process-steps.mjs +132 -0
- package/fesm2022/tekus-design-system-components-process-steps.mjs.map +1 -0
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs +20 -6
- package/fesm2022/tekus-design-system-components-sidebar-layout.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-stepper.mjs +1 -1
- package/fesm2022/tekus-design-system-components-stepper.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-table.mjs +1 -1
- package/fesm2022/tekus-design-system-components-table.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toast.mjs +1 -1
- package/fesm2022/tekus-design-system-components-toast.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-toolbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs +1 -1
- package/fesm2022/tekus-design-system-components-topbar.mjs.map +1 -1
- package/fesm2022/tekus-design-system-components-uploader.mjs +1256 -0
- package/fesm2022/tekus-design-system-components-uploader.mjs.map +1 -0
- package/package.json +17 -1
- package/types/tekus-design-system-components-button.d.ts +20 -1
- package/types/tekus-design-system-components-carousel.d.ts +200 -0
- package/types/tekus-design-system-components-header.d.ts +33 -0
- package/types/tekus-design-system-components-modal.d.ts +31 -13
- package/types/tekus-design-system-components-process-steps.d.ts +72 -0
- package/types/tekus-design-system-components-sidebar-layout.d.ts +11 -1
- package/types/tekus-design-system-components-uploader.d.ts +524 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tekus-design-system-components-uploader.mjs","sources":["../../../projects/design-system/components/uploader/src/tokens/uploader.tokens.ts","../../../projects/design-system/components/uploader/src/composable/upload-strategies.helper.ts","../../../projects/design-system/components/uploader/src/composable/uploader-defaults.helper.ts","../../../projects/design-system/components/uploader/src/composable/uploader-validator.helper.ts","../../../projects/design-system/components/uploader/src/services/uploader-queue.service.ts","../../../projects/design-system/components/uploader/src/sections/file-card.component.ts","../../../projects/design-system/components/uploader/src/sections/file-card.component.html","../../../projects/design-system/components/uploader/src/uploader.component.ts","../../../projects/design-system/components/uploader/src/uploader.component.html","../../../projects/design-system/components/uploader/src/services/uploader-store.service.ts","../../../projects/design-system/components/uploader/src/services/uploader-preview.service.ts","../../../projects/design-system/components/uploader/src/services/upload-transport.service.ts","../../../projects/design-system/components/uploader/src/services/provide-uploader.ts","../../../projects/design-system/components/uploader/tekus-design-system-components-uploader.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\nimport {\n IUploaderPreviewProvider,\n IUploaderStore,\n IUploaderTransport\n} from '../types/uploader-item.types';\n\n/** Queue backing store — provided by `provideUploader()`, actively injected by `UploaderQueueService`. */\nexport const UPLOADER_STORE = new InjectionToken<IUploaderStore>(\n 'UPLOADER_STORE'\n);\n/** Client-side preview/metadata generator — provided by `provideUploader()`, actively injected internally. */\nexport const UPLOADER_PREVIEW_PROVIDER = new InjectionToken<IUploaderPreviewProvider>(\n 'UPLOADER_PREVIEW_PROVIDER'\n);\n/**\n * HTTP transport — provided by `provideUploader()`, but never injected\n * internally. Registered purely so the consumer's own `steps`/\n * `multipart.uploadPart` functions can `inject(UPLOADER_TRANSPORT)` instead\n * of instantiating `HttpClient` themselves.\n */\nexport const UPLOADER_TRANSPORT = new InjectionToken<IUploaderTransport>(\n 'UPLOADER_TRANSPORT'\n);\n","import {\n Observable,\n from,\n throwError,\n EMPTY,\n timer,\n catchError,\n concatMap,\n defaultIfEmpty,\n expand,\n map,\n takeWhile,\n toArray,\n tap,\n last,\n filter\n} from 'rxjs';\n\nimport {\n MultipartConfig,\n UploadFlowConfig,\n UploadStep\n} from '../types/uploader-contracts.types';\nimport { PollingResponse } from '../types/uploader.types';\nimport {\n UploadContext,\n StepParams,\n UploadPartParams\n} from '../types/uploader-params.types';\nimport {\n UploadItem,\n IUploaderStore\n} from '../types/uploader-item.types';\n\nexport interface UploadStrategyParams<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n item: UploadItem<T>;\n payload: T | undefined;\n context: UploadContext<C>;\n config: UploadFlowConfig<T, C>;\n store: IUploaderStore<T>;\n handleError: (\n id: string,\n err: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ) => void;\n reportProgress: (progress: number, text?: string) => void;\n}\n\n/** Runs `config.steps` one after another, reporting progress as each resolves. */\nexport function runSequentialStepsFlow<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: UploadStrategyParams<T, C>): Observable<C> {\n const { item, payload, context, config, store, handleError, reportProgress } =\n params;\n const steps = config.steps || [];\n const totalSteps = steps.length;\n\n return from(steps).pipe(\n concatMap((step, index) => {\n return executeStep(\n step,\n { file: item.file, context, payload, item },\n index,\n totalSteps,\n store,\n config,\n reportProgress\n ).pipe(\n catchError((err) => {\n handleError(item.id, err, config, context);\n return throwError(() => err);\n })\n );\n }),\n toArray(),\n map(() => context)\n );\n}\n\n/** Runs `config.multipart`: `init` → chunks sequentially via `uploadPart` → `complete`. */\nexport function runMultipartFlow<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: UploadStrategyParams<T, C>): Observable<C> {\n const { item, payload, context, config, store, handleError, reportProgress } =\n params;\n const multipart = config.multipart!;\n const chunkSize = multipart.chunkSizeMB * 1024 * 1024;\n const totalChunks = Math.ceil(item.file.size / chunkSize);\n\n return multipart.init({ file: item.file, payload }).pipe(\n map((initResult) => {\n Object.assign(context as Record<string, unknown>, initResult);\n reportProgress(0);\n return { partNumber: 0 };\n }),\n\n expand(({ partNumber }: { partNumber: number }) => {\n if (partNumber >= totalChunks) {\n return EMPTY;\n }\n\n const start = partNumber * chunkSize;\n const end = Math.min(start + chunkSize, item.file.size);\n const chunk = item.file.slice(start, end);\n return executeChunk(\n multipart,\n {\n file: item.file,\n chunk,\n partNumber,\n context,\n payload,\n metadata: item.metadata\n },\n totalChunks,\n store,\n item.id,\n config,\n reportProgress\n );\n }),\n\n takeWhile(({ partNumber }) => partNumber <= totalChunks, true),\n toArray(),\n concatMap(() => {\n const scale = 100 / (config.totalSteps || 1);\n reportProgress(\n Math.round(scale),\n config.resolveText?.('FINISHING') ?? 'FINISHING'\n );\n return multipart.complete({ context, payload }).pipe(\n map(() => {\n return context;\n })\n );\n }),\n catchError((err) => {\n handleError(item.id, err, config, context);\n return throwError(() => err);\n })\n );\n}\n\nexport interface PollingStrategyParams<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n id: string;\n payload: T | undefined;\n context: UploadContext<C>;\n config: UploadFlowConfig<T, C>;\n store: IUploaderStore<T>;\n handleError: (\n id: string,\n err: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ) => void;\n}\n\n/**\n * Runs `config.polling` after the byte upload succeeds: calls `checkStatus`\n * every `intervalMs`, merging `progress`/`statusText`/`steps`/`stepsStatus`/\n * `stepsTitle`/`stepsDescription`/`stepsCountdownSeconds`/`stepsCountdownLabel`\n * into the item as they arrive, until `status` stops being `'loading'`.\n */\nexport function runPolling<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n>(params: PollingStrategyParams<T, C>): Observable<PollingResponse> {\n const { id, payload, context, config, store, handleError } = params;\n const pollConfig = config.polling!;\n const interval = pollConfig.intervalMs || 3000;\n\n return timer(0, interval).pipe(\n concatMap(() => pollConfig.checkStatus({ context, payload })),\n takeWhile((response) => response.status === 'loading', true),\n map((response) => {\n if (response.status === 'error') {\n throw new Error(response.error || 'POLLING_FAILED');\n }\n\n const updates: Partial<UploadItem<T>> = {};\n if (response.progress !== undefined) {\n updates.progress = response.progress;\n }\n if (response.statusText !== undefined) {\n updates.statusText = response.statusText;\n }\n if (response.steps !== undefined) {\n updates.steps = response.steps;\n }\n if (response.stepsStatus !== undefined) {\n updates.stepsStatus = response.stepsStatus;\n }\n if (response.stepsTitle !== undefined) {\n updates.stepsTitle = response.stepsTitle;\n }\n if (response.stepsDescription !== undefined) {\n updates.stepsDescription = response.stepsDescription;\n }\n if (response.stepsCountdownSeconds !== undefined) {\n updates.stepsCountdownSeconds = response.stepsCountdownSeconds;\n }\n if (response.stepsCountdownLabel !== undefined) {\n updates.stepsCountdownLabel = response.stepsCountdownLabel;\n }\n\n if (Object.keys(updates).length > 0) {\n store.update(id, updates);\n }\n return response;\n }),\n catchError((err) => {\n handleError(id, err, config, context);\n return throwError(() => err);\n }),\n toArray(),\n map((responses) => responses.at(-1)!)\n );\n}\n\nfunction executeStep<T, C extends Record<string, unknown>>(\n step: UploadStep<T, C>,\n params: StepParams<T, C>,\n index: number,\n totalSteps: number,\n store: IUploaderStore<T>,\n config: UploadFlowConfig<T, C>,\n reportProgress: (progress: number, text?: string) => void\n): Observable<C> {\n const scale = 100 / (config.totalSteps || 1);\n return step(params).pipe(\n map((result) => {\n Object.assign(params.context as Record<string, unknown>, result);\n const id = params.item?.id;\n if (id) {\n const progress = Math.round(((index + 1) / totalSteps) * scale);\n reportProgress(progress);\n }\n config.hooks?.onStepComplete?.({\n stepIndex: index,\n context: params.context\n });\n return params.context;\n })\n );\n}\n\nfunction executeChunk<T, C extends Record<string, unknown>>(\n multipart: MultipartConfig<T, C>,\n params: UploadPartParams<T, C>,\n totalChunks: number,\n store: IUploaderStore<T>,\n itemId: string,\n config: UploadFlowConfig<T, C>,\n reportProgress: (progress: number, text?: string) => void\n): Observable<{ partNumber: number }> {\n const scale = 100 / (config.totalSteps || 1);\n return multipart.uploadPart(params).pipe(\n tap((val: number | string | Partial<C>) => {\n if (typeof val === 'number' && totalChunks > 0) {\n const currentPartOffset = (params.partNumber / totalChunks) * scale;\n const chunkContribution = (val / 100) * (scale / totalChunks);\n reportProgress(Math.round(currentPartOffset + chunkContribution));\n }\n }),\n filter(\n (val: number | string | Partial<C>) =>\n typeof val === 'object' && val !== null\n ),\n defaultIfEmpty({} as Partial<C>),\n last(),\n map((result) => {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n Object.assign(params.context as Record<string, unknown>, result);\n }\n\n const progress =\n totalChunks > 0\n ? Math.round(((params.partNumber + 1) / totalChunks) * scale)\n : Math.round(scale);\n reportProgress(progress);\n return { partNumber: params.partNumber + 1 };\n })\n );\n}\n","import { UploadFlowConfig } from '../types/uploader-contracts.types';\n\n/** Fallback values applied by `mergeConfigWithDefaults` when the consumer omits them. */\nexport const UPLOADER_DEFAULTS = {\n chunkSizeMB: 5,\n concurrencyLimit: 4,\n pollingIntervalMs: 3000\n};\n\n/** Fills in `UPLOADER_DEFAULTS` for whatever `config` leaves unset — never overrides an explicit value. */\nexport function mergeConfigWithDefaults<T, C extends Record<string, unknown>>(\n config: UploadFlowConfig<T, C>\n): UploadFlowConfig<T, C> {\n let refined = { ...config };\n\n if (refined.concurrencyLimit === undefined) {\n refined = {\n ...refined,\n concurrencyLimit: UPLOADER_DEFAULTS.concurrencyLimit\n };\n }\n\n if (refined.multipart) {\n refined = {\n ...refined,\n multipart: {\n ...refined.multipart,\n chunkSizeMB:\n refined.multipart.chunkSizeMB ?? UPLOADER_DEFAULTS.chunkSizeMB\n }\n };\n }\n\n if (refined.polling) {\n refined = {\n ...refined,\n polling: {\n ...refined.polling,\n intervalMs:\n refined.polling.intervalMs ?? UPLOADER_DEFAULTS.pollingIntervalMs\n }\n };\n }\n\n return refined;\n}\n","import { FileRestrictions, RestrictionRule } from '../types/uploader.types';\n\n/** `error` is an `UploaderErrorCode` when `isValid` is `false`. */\nexport interface ValidationResult {\n isValid: boolean;\n error?: string;\n detail?: unknown;\n}\n\n/** Checks a file against `UploadFlowConfig.restrictions` before it's queued. */\nexport class UploaderValidator {\n /**\n * Checks integrity (non-empty) first, then extension/size — `rules` (per-extension\n * `maxSizeMB`) if set, otherwise the legacy `allowedExtensions`/`maxSizeMB` pair.\n */\n static validate(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const integrityResult = this.checkFileIntegrity(file);\n if (!integrityResult.isValid) {\n return integrityResult;\n }\n\n return restrictions.rules?.length\n ? this.checkGranularRules(file, restrictions.rules)\n : this.checkLegacyRestrictions(file, restrictions);\n }\n\n private static checkFileIntegrity(file: File): ValidationResult {\n if (file.size === 0) {\n return {\n isValid: false,\n error: 'FILE_CORRUPT',\n detail: { fileName: file.name, fileSize: 0 }\n };\n }\n return { isValid: true };\n }\n\n private static checkGranularRules(\n file: File,\n rules: RestrictionRule[]\n ): ValidationResult {\n const fileName = file.name.toLowerCase();\n const matchingRule = rules.find(rule =>\n rule.extensions.some(ext => fileName.endsWith(ext.toLowerCase()))\n );\n\n return matchingRule\n ? this.checkRuleMaxSize(file, matchingRule)\n : this.buildGranularInvalidFormatResult(fileName, rules);\n }\n\n private static buildGranularInvalidFormatResult(\n fileName: string,\n rules: RestrictionRule[]\n ): ValidationResult {\n return {\n isValid: false,\n error: 'INVALID_FORMAT',\n detail: {\n fileName,\n allowedExtensionsByType: rules.map(rule => rule.extensions)\n }\n };\n }\n\n private static checkRuleMaxSize(\n file: File,\n rule: RestrictionRule\n ): ValidationResult {\n if (rule.maxSizeMB !== undefined && file.size > rule.maxSizeMB * 1024 * 1024) {\n return {\n isValid: false,\n error: 'FILE_TOO_LARGE',\n detail: { fileSize: file.size, maxSizeMB: rule.maxSizeMB }\n };\n }\n return { isValid: true };\n }\n\n private static checkLegacyRestrictions(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const maxSizeResult = this.checkLegacyMaxSize(file, restrictions);\n if (!maxSizeResult.isValid) {\n return maxSizeResult;\n }\n\n return this.checkLegacyExtension(file, restrictions);\n }\n\n private static checkLegacyMaxSize(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n if (\n restrictions.maxSizeMB &&\n file.size > restrictions.maxSizeMB * 1024 * 1024\n ) {\n return {\n isValid: false,\n error: 'FILE_TOO_LARGE',\n detail: { fileSize: file.size, maxSizeMB: restrictions.maxSizeMB }\n };\n }\n return { isValid: true };\n }\n\n private static checkLegacyExtension(\n file: File,\n restrictions: FileRestrictions\n ): ValidationResult {\n const fileName = file.name.toLowerCase();\n const isAllowed =\n !restrictions.allowedExtensions ||\n restrictions.allowedExtensions.some(ext =>\n fileName.endsWith(ext.toLowerCase())\n );\n\n return isAllowed\n ? { isValid: true }\n : this.buildLegacyInvalidFormatResult(fileName, restrictions);\n }\n\n private static buildLegacyInvalidFormatResult(\n fileName: string,\n restrictions: FileRestrictions\n ): ValidationResult {\n return {\n isValid: false,\n error: 'INVALID_FORMAT',\n detail: { fileName, allowedExtensions: restrictions.allowedExtensions }\n };\n }\n}\n","import {\n computed,\n inject,\n Injectable,\n untracked,\n runInInjectionContext,\n Injector,\n signal,\n OnDestroy\n} from '@angular/core';\nimport { toObservable } from '@angular/core/rxjs-interop';\nimport {\n MediaAnalysis,\n UploaderErrorCode,\n UploaderStatus\n} from '../types/uploader.types';\nimport { UploadFlowConfig } from '../types/uploader-contracts.types';\nimport {\n UploadItem,\n AuditEntry,\n IUploaderStore\n} from '../types/uploader-item.types';\nimport { UploadContext } from '../types/uploader-params.types';\nimport {\n UPLOADER_STORE,\n UPLOADER_PREVIEW_PROVIDER\n} from '../tokens/uploader.tokens';\nimport {\n concatMap,\n of,\n Subscription,\n finalize,\n take,\n filter,\n firstValueFrom,\n isObservable,\n catchError,\n Observable,\n throwError\n} from 'rxjs';\nimport {\n runSequentialStepsFlow,\n runMultipartFlow,\n runPolling,\n UploadStrategyParams\n} from '../composable/upload-strategies.helper';\nimport { mergeConfigWithDefaults } from '../composable/uploader-defaults.helper';\nimport { UploaderValidator } from '../composable/uploader-validator.helper';\n\nconst STATUS_KEY_MAP: Partial<Record<UploaderStatus, string>> = {\n loading: 'UPLOAD_IN_PROGRESS',\n success: 'FULL_LOAD',\n error: 'LOAD_ERROR',\n ready: 'READY',\n analyzing: 'ANALYZING',\n transforming: 'TRANSFORMING',\n queued: 'PROCESSING'\n};\n\nconst ERROR_CODES: ReadonlySet<UploaderErrorCode> = new Set([\n 'FILE_CORRUPT',\n 'INVALID_FORMAT',\n 'FILE_TOO_LARGE',\n 'ANALYSIS_FAILED',\n 'PROCESS_FAILED',\n 'EXTERNAL_VALIDATION_FAILED',\n 'POLLING_FAILED',\n 'NO_UPLOAD_STRATEGY_CONFIGURED'\n]);\n\n/**\n * The engine — orchestrates the whole upload flow (validation, analysis,\n * transform, `steps`/`multipart`, `polling`, lifecycle hooks) driven purely\n * by the `UploadFlowConfig` passed to `addToQueue`. Not `providedIn: 'root'`;\n * `provideUploader()` gives each `tk-uploader` its own instance.\n */\n@Injectable()\nexport class UploaderQueueService<\n C extends Record<string, unknown> = Record<string, unknown>\n> implements OnDestroy {\n private readonly store = inject<IUploaderStore<unknown>>(UPLOADER_STORE);\n private readonly previewProvider = inject(UPLOADER_PREVIEW_PROVIDER);\n private readonly injector = inject(Injector);\n private readonly activeSubscriptions = new Map<string, Subscription>();\n private readonly isManualTriggered = signal(false);\n private currentConfig?: UploadFlowConfig<unknown, C>;\n\n public readonly uploadQueue = this.store.uploadQueue;\n\n /** Every state transition recorded so far — not currently surfaced anywhere by default. */\n public readonly auditHistory = signal<AuditEntry[]>([]);\n\n /** Whether any item is actively `loading` right now. */\n public readonly isUploading = computed(() =>\n this.uploadQueue().some((i) => i.status === 'loading')\n );\n\n /** Whether any item is mid-flight (`analyzing`/`transforming`/`loading`) — client-side or network work in progress. */\n public readonly isBusy = computed(() =>\n this.uploadQueue().some((i) =>\n ['analyzing', 'transforming', 'loading'].includes(i.status)\n )\n );\n\n /** `!isBusy()` — whether it's safe to close/navigate away without losing in-flight work. */\n public readonly canSafetyClose = computed(() => !this.isBusy());\n\n ngOnDestroy(): void {\n this.clearQueue();\n }\n\n /**\n * Adds one or more files to the queue and starts them through validation →\n * analysis → transform → (auto-start or wait for `startUpload`/`startAllReady`).\n * `config` becomes `currentConfig`, reused by every later call until the next `addToQueue`.\n */\n addToQueue<T = unknown>(\n files: File | File[],\n config: UploadFlowConfig<T, C>\n ): void {\n this.isManualTriggered.set(false);\n const mergedConfig = mergeConfigWithDefaults(config);\n this.currentConfig = mergedConfig as unknown as UploadFlowConfig<\n unknown,\n C\n >;\n const fileList = Array.isArray(files) ? files : [files];\n\n fileList.forEach((file) => {\n const id = crypto.randomUUID();\n const newItem: UploadItem<T> = {\n id,\n file,\n progress: 0,\n status: 'analyzing',\n statusKey: this.getStatusKey('analyzing'),\n statusText: this.getStatusText('analyzing')\n };\n\n this.addAuditEntry(id, 'none', 'analyzing');\n this.store.add(newItem as UploadItem<unknown>);\n mergedConfig.hooks?.onFileAdded?.(file);\n\n untracked(() => {\n if (mergedConfig.restrictions) {\n const result = UploaderValidator.validate(file, mergedConfig.restrictions);\n if (!result.isValid) {\n this.handleError(\n id,\n result.error,\n mergedConfig,\n undefined,\n result.detail,\n 'invalid'\n );\n return;\n }\n }\n this.runAnalysis(id, file, mergedConfig);\n });\n });\n }\n\n private runAnalysis<T>(\n id: string,\n file: File,\n config: UploadFlowConfig<T, C>\n ): void {\n const analysisResource = runInInjectionContext(this.injector, () =>\n this.previewProvider.generatePreview(file)\n );\n\n const sub = toObservable<MediaAnalysis | undefined>(\n analysisResource.value,\n {\n injector: this.injector\n }\n )\n .pipe(\n filter((val) => !!val),\n take(1),\n finalize(() => {\n this.activeSubscriptions.delete(`${id}_analysis`);\n analysisResource.destroy();\n })\n )\n .subscribe((analysis) => {\n if (analysis) {\n this.handleAnalysisResult<T>(id, analysis, config);\n }\n });\n\n this.activeSubscriptions.set(`${id}_analysis`, sub);\n }\n\n private async handleAnalysisResult<T>(\n id: string,\n analysis: MediaAnalysis,\n config: UploadFlowConfig<T, C>\n ): Promise<void> {\n if (!this.uploadQueue().some((i) => i.id === id)) {\n // The item was removed while analysis was still in flight — the store never\n // got `previewUrl`, so `removeFromQueue`'s own revoke couldn't find it either.\n if (analysis.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(analysis.previewUrl);\n }\n return;\n }\n\n if (analysis.analysisError) {\n const errorKey = analysis.technicalError || 'ANALYSIS_FAILED';\n this.handleError(\n id,\n errorKey,\n config,\n {} as unknown as C,\n analysis.technicalError\n );\n return;\n }\n\n this.patchItem(id, {\n previewUrl: analysis.previewUrl,\n previewBlob: analysis.previewBlob,\n previewBase64: analysis.previewBase64,\n metadata: analysis.metadata\n });\n\n const isValid = await this.validateExternalRestrictions<T>(\n id,\n analysis,\n config\n );\n if (!isValid) {\n return;\n }\n\n await this.runTransformation<T>(id, config);\n }\n\n private async validateExternalRestrictions<T>(\n id: string,\n analysis: MediaAnalysis,\n config: UploadFlowConfig<T, C>\n ): Promise<boolean | undefined> {\n if (config.hooks?.validate) {\n let validation: boolean | string;\n const validation$ = config.hooks.validate({\n file: (this.uploadQueue().find((i) => i.id === id) as UploadItem<T>)\n .file,\n metadata: analysis.metadata\n });\n\n if (isObservable(validation$)) {\n validation = await firstValueFrom(\n validation$.pipe(catchError(() => of(false as boolean | string)))\n );\n } else {\n validation = validation$;\n }\n\n if (validation !== true) {\n this.handleError<T>(\n id,\n typeof validation === 'string' && validation\n ? new Error(validation)\n : new Error('EXTERNAL_VALIDATION_FAILED'),\n config,\n {} as unknown as C\n );\n return;\n }\n }\n return true;\n }\n\n private async runTransformation<T>(\n id: string,\n config: UploadFlowConfig<T, C>\n ): Promise<void> {\n if (config.hooks?.onTransform) {\n this.patchItem(id, { status: 'transforming' });\n try {\n const item = this.uploadQueue().find((i) => i.id === id)!;\n const payload = await (\n config.hooks.onTransform as (\n item: UploadItem<unknown>\n ) => Promise<T> | T\n )(item);\n this.patchItem(id, { payload });\n } catch (err) {\n this.handleError<T>(id, err, config, {} as unknown as C);\n return;\n }\n }\n\n const isAutoStart =\n typeof config.autoStart === 'function'\n ? config.autoStart()\n : config.autoStart;\n\n if (isAutoStart !== false || this.isManualTriggered()) {\n this.patchItem(id, { status: 'queued' });\n this.checkConcurrencyAndProcess(config);\n } else {\n this.patchItem(id, { status: 'ready' });\n }\n }\n\n /** Manually starts a single `ready` item (when `autoStart` is `false`). */\n startUpload(id: string): void {\n if (!this.currentConfig) {\n return;\n }\n this.patchItem(id, { status: 'queued' });\n this.checkConcurrencyAndProcess(this.currentConfig);\n }\n\n /** Manually starts every `ready` item at once (when `autoStart` is `false`). */\n startAllReady(): void {\n if (!this.currentConfig) {\n return;\n }\n this.isManualTriggered.set(true);\n this.uploadQueue().forEach((item) => {\n if (item.status === 'ready') {\n this.patchItem(item.id, { status: 'queued' });\n }\n });\n this.checkConcurrencyAndProcess(this.currentConfig);\n }\n\n private checkConcurrencyAndProcess<T>(config: UploadFlowConfig<T, C>): void {\n const limit = config.concurrencyLimit!;\n const activeCount = this.uploadQueue().filter(\n (i: UploadItem<unknown>) => i.status === 'loading'\n ).length;\n\n if (activeCount < limit) {\n const nextItem = this.uploadQueue().find(\n (i: UploadItem<unknown>) => i.status === 'queued'\n );\n if (nextItem) {\n this.processUpload(nextItem as UploadItem<T>, config);\n this.checkConcurrencyAndProcess(config);\n }\n }\n }\n\n private processUpload<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>\n ): void {\n const context: UploadContext<C> = {} as unknown as C;\n this.startUploadFlow(item, config);\n\n const subscription = this.getExecutionStream(item, config, context)\n .pipe(\n concatMap(() => {\n if (config.polling) {\n return runPolling<T, C>({\n id: item.id,\n payload: item.payload,\n context,\n config,\n store: this.store as unknown as IUploaderStore<T>,\n handleError: this.handleError.bind(this)\n });\n }\n return of(context);\n }),\n finalize(() => this.finalizeItem(item.id, config))\n )\n .subscribe({\n next: () => {\n this.patchItem(item.id, { status: 'success', progress: 100 });\n config.hooks?.onSuccess?.({ context, payload: item.payload });\n this.checkAllComplete(config);\n },\n error: () => this.checkAllComplete(config)\n });\n\n this.activeSubscriptions.set(item.id, subscription);\n }\n\n private startUploadFlow<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>\n ): void {\n this.patchItem(item.id, {\n status: 'loading',\n progress: 0,\n statusText: this.getStatusText('loading')\n });\n config.hooks?.onBeforeStart?.(item.file);\n }\n\n private getExecutionStream<T>(\n item: UploadItem<T>,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C>\n ): Observable<C> {\n if (!config.multipart && !config.steps?.length) {\n const error = new Error('NO_UPLOAD_STRATEGY_CONFIGURED');\n this.handleError(item.id, error, config, context);\n return throwError(() => error);\n }\n\n const params: UploadStrategyParams<T, C> = {\n item,\n payload: item.payload,\n context,\n config,\n store: this.store as unknown as IUploaderStore<T>,\n handleError: this.handleError.bind(this),\n reportProgress: (progress: number, text?: string) =>\n this.patchItem(item.id, { progress, statusText: text })\n };\n\n return config.multipart\n ? runMultipartFlow<T, C>(params)\n : runSequentialStepsFlow<T, C>(params);\n }\n\n private finalizeItem<T>(id: string, config: UploadFlowConfig<T, C>): void {\n this.activeSubscriptions.delete(id);\n this.checkConcurrencyAndProcess(config);\n }\n\n private extractErrorCode(error: unknown): UploaderErrorCode | undefined {\n if (typeof error === 'string' && ERROR_CODES.has(error as UploaderErrorCode)) {\n return error as UploaderErrorCode;\n }\n if (\n error instanceof Error &&\n ERROR_CODES.has(error.message as UploaderErrorCode)\n ) {\n return error.message as UploaderErrorCode;\n }\n return undefined;\n }\n\n private getErrorText(error: unknown): string {\n const code = this.extractErrorCode(error);\n if (code) {\n return this.resolveUploaderKeyText(code);\n }\n if (error instanceof Error) {\n return error.message;\n }\n if (typeof error === 'string') {\n return error;\n }\n return this.getStatusText('error');\n }\n\n private resolveUploaderKeyText(key: string): string {\n return this.currentConfig?.resolveText\n ? this.currentConfig.resolveText(key)\n : key;\n }\n\n private handleError<T>(\n id: string,\n error: unknown,\n config: UploadFlowConfig<T, C>,\n context: UploadContext<C> | undefined = undefined,\n detail?: unknown,\n status: UploaderStatus = 'error'\n ): void {\n const errorMessage = this.getErrorText(error);\n\n this.patchItem(\n id,\n {\n status,\n error: errorMessage\n },\n detail\n );\n\n config.hooks?.onError?.({ error, context });\n }\n\n private checkAllComplete<T>(config: UploadFlowConfig<T, C>): void {\n const allTerminal = this.uploadQueue().every((i: UploadItem<unknown>) =>\n ['success', 'error', 'invalid'].includes(i.status)\n );\n if (allTerminal) {\n this.isManualTriggered.set(false);\n config.hooks?.onAllComplete?.();\n }\n }\n\n /**\n * Removes an item outright — revokes its preview blob URL and cancels any\n * in-flight upload subscription first. This is outside `UploadFlowConfig`'s\n * contract on purpose: `tk-uploader` only ever reports a removal request\n * (see `UploaderRemoveRequest`/`removeRequested`), the consumer decides\n * whether/when to actually call this.\n *\n * Deliberately does NOT cancel a still-pending `${id}_analysis` subscription:\n * doing so would drop the analysis result (and any blob URL it already created)\n * on the floor with nothing left to revoke it. Letting it resolve naturally lets\n * `handleAnalysisResult`'s own \"item still in the queue?\" check catch it instead.\n */\n removeFromQueue(id: string): void {\n this.revokeItemPreview(id);\n this.cancelSubscription(id);\n this.store.remove(id);\n }\n\n private revokeItemPreview(id: string): void {\n const item = this.uploadQueue().find((i) => i.id === id);\n if (item?.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(item.previewUrl);\n }\n }\n\n private cancelSubscription(key: string): void {\n const sub = this.activeSubscriptions.get(key);\n if (sub) {\n sub.unsubscribe();\n this.activeSubscriptions.delete(key);\n }\n }\n\n /** Cancels an item's in-flight subscription without removing it — `startUpload` resumes it. */\n pauseUpload(id: string): void {\n this.cancelSubscription(id);\n }\n\n /** Revokes every preview blob URL, cancels every in-flight subscription, and empties the store. */\n clearQueue(): void {\n this.uploadQueue().forEach((item) => {\n if (item.previewUrl?.startsWith('blob:')) {\n URL.revokeObjectURL(item.previewUrl);\n }\n });\n\n this.activeSubscriptions.forEach((sub) => sub.unsubscribe());\n this.activeSubscriptions.clear();\n this.store.clear();\n }\n\n private getStatusKey(status: UploaderStatus): string {\n return STATUS_KEY_MAP[status] || status.toUpperCase();\n }\n\n private getStatusText(status: UploaderStatus): string {\n const key = this.getStatusKey(status);\n if (this.currentConfig?.resolveText) {\n return this.currentConfig.resolveText(key);\n }\n return status;\n }\n\n private patchItem<T>(\n id: string,\n updates: Partial<UploadItem<T>>,\n detail?: unknown\n ): void {\n const currentItem = this.uploadQueue().find((i) => i.id === id);\n if (!currentItem) {\n return;\n }\n\n if (updates.status && updates.status !== currentItem.status) {\n this.addAuditEntry(id, currentItem.status, updates.status, detail);\n updates.statusKey = this.getStatusKey(updates.status);\n updates.statusText ??= this.getStatusText(updates.status);\n }\n\n const cleanUpdates = { ...updates };\n if (cleanUpdates.statusText === undefined) {\n delete cleanUpdates.statusText;\n }\n\n this.store.update(id, cleanUpdates);\n }\n\n private addAuditEntry(\n itemId: string,\n from: UploaderStatus | 'none',\n toStatus: UploaderStatus,\n detail?: unknown\n ): void {\n this.auditHistory.update((history) => [\n ...history,\n {\n itemId,\n from,\n to: toStatus,\n timestamp: Date.now(),\n key: this.getStatusKey(toStatus),\n errorDetail: detail\n }\n ]);\n }\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n input,\n output\n} from '@angular/core';\n\nimport { ButtonComponent, ButtonSeverity } from '@tekus/design-system/components/button';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ProgressBarComponent } from '@tekus/design-system/components/progress-bar';\nimport { UploaderStatus } from '../types/uploader.types';\n\n/**\n * Horizontal file card — icon/preview, title, plain progress bar while\n * `status` is `'loading'` (otherwise `statusText`), and a trailing action\n * button. Internal to `tk-uploader`; not part of the public API.\n */\n@Component({\n selector: 'tk-uploader-file-card',\n standalone: true,\n imports: [ButtonComponent, IconComponent, ProgressBarComponent],\n templateUrl: './file-card.component.html',\n styleUrl: './file-card.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UploaderFileCardComponent {\n readonly title = input.required<string>();\n readonly status = input.required<UploaderStatus>();\n /** 0-100, shown only while `status` is `'loading'`. */\n readonly progress = input<number>(0);\n readonly previewUrl = input<string | null>();\n /** Fallback icon shown when there's no `previewUrl`. */\n readonly icon = input<string>('folders');\n\n /** Shown instead of the progress bar whenever `status` isn't `'loading'`. */\n readonly statusText = input.required<string>();\n /**\n * Set by the consumer while it's waiting on its own confirmation for this\n * item's removal — this card never confirms anything itself, it only\n * reflects that a decision is pending by disabling the remove button (no\n * double-clicks while waiting).\n */\n readonly isPendingRemoval = input<boolean>(false);\n /**\n * Icon for the trailing button — defaults to the remove affordance\n * (`trash-can`). `tk-uploader` overrides this for its `placeholder` card,\n * where the same button re-opens the file picker instead of removing\n * anything (there's nothing in the real queue to remove).\n */\n readonly trailingIcon = input<string>('trash-can');\n /** Severity for the trailing button — `danger` reads as destructive, `secondary` doesn't. */\n readonly trailingSeverity = input<ButtonSeverity>('danger');\n /**\n * Tooltip/accessible label for the trailing button — this card has no copy of its own\n * (no i18n coupling, same reasoning as `UploadFlowConfig.resolveText`), so it stays\n * unlabeled unless the consumer supplies text here.\n */\n readonly trailingLabel = input<string>();\n /** Emitted on trailing-button click — its meaning depends on `trailingIcon`/context, this card has no opinion on it. */\n readonly dismissed = output<void>();\n\n protected readonly isProcessing = computed(() => this.status() === 'loading');\n}\n","<article class=\"tk-uploader-file-card\" [attr.data-status]=\"status()\">\n <div class=\"tk-uploader-file-card__media\">\n @if (previewUrl()) {\n <img\n [src]=\"previewUrl()\"\n alt=\"File preview\"\n class=\"tk-uploader-file-card__preview\" />\n } @else {\n <tk-icon [icon]=\"icon()\" class=\"tk-uploader-file-card__media-icon\" />\n }\n </div>\n\n <div class=\"tk-uploader-file-card__info\">\n <h4 class=\"tk-uploader-file-card__title\">{{ title() }}</h4>\n\n @if (isProcessing()) {\n <!-- statusText is intentionally hidden while loading: tk-progress-bar only shows a\n number, so with multiple files (no per-item tk-process-steps) there's no textual\n feedback during this state — see uploader.mdx \"Known limitations\". -->\n <div class=\"tk-uploader-file-card__progress\">\n <tk-progress-bar [value]=\"progress()\" size=\"medium\" [showValue]=\"true\" />\n </div>\n } @else {\n <p class=\"tk-uploader-file-card__status-text\">{{ statusText() }}</p>\n }\n </div>\n\n <tk-button\n variant=\"outlined\"\n [severity]=\"trailingSeverity()\"\n size=\"small\"\n [icon]=\"trailingIcon()\"\n [tooltipText]=\"trailingLabel()\"\n class=\"tk-uploader-file-card__remove\"\n [disabled]=\"isPendingRemoval()\"\n (clicked)=\"dismissed.emit()\" />\n</article>\n","import {\n ChangeDetectionStrategy,\n Component,\n computed,\n ElementRef,\n inject,\n input,\n output,\n signal,\n viewChild\n} from '@angular/core';\n\nimport { UploadFlowConfig } from './types/uploader-contracts.types';\nimport { IconComponent } from '@tekus/design-system/components/icon';\nimport { ProcessStepsComponent } from '@tekus/design-system/components/process-steps';\nimport { UploaderQueueService } from './services/uploader-queue.service';\nimport { UploaderFileCardComponent } from './sections/file-card.component';\nimport { LoaderPlaceholder } from './types/uploader-placeholder.types';\nimport {\n UploaderRemovePhase,\n UploaderRemoveRequest,\n UploaderStatus\n} from './types/uploader.types';\n\nconst TERMINAL_STATUSES: ReadonlySet<UploaderStatus> = new Set(['success', 'error', 'invalid']);\nconst DEFAULT_STEPS_TITLE = 'Processing';\n\nfunction resolveRemovePhase(status: UploaderStatus): UploaderRemovePhase {\n if (status === 'loading') {\n return 'in-progress';\n }\n return TERMINAL_STATUSES.has(status) ? 'post-upload' : 'pre-upload';\n}\n\n/**\n * Drag-and-drop upload zone with a queue of file cards. Fully agnostic: it\n * has no opinion on *how* a file gets uploaded — validation, upload\n * mechanics, post-upload polling and every lifecycle callback are supplied\n * by the consumer through `config` (`UploadFlowConfig`). Requires\n * `provideUploader()` in the providers of the hosting component (or a parent).\n */\n@Component({\n selector: 'tk-uploader',\n standalone: true,\n imports: [UploaderFileCardComponent, IconComponent, ProcessStepsComponent],\n templateUrl: './uploader.component.html',\n styleUrl: './uploader.component.scss',\n changeDetection: ChangeDetectionStrategy.OnPush\n})\nexport class UploaderComponent<\n T = unknown,\n C extends Record<string, unknown> = Record<string, unknown>\n> {\n private readonly queueService = inject<UploaderQueueService<C>>(\n UploaderQueueService\n );\n\n /** Idle-state heading, shown before any file is selected. */\n title = input<string>('Drag and drop your file here');\n /** Whether more than one file can be added to the queue at once. */\n multiple = input<boolean>(false);\n /** Idle-state helper text. */\n subtitle = input<string>('or click to browse');\n /** Optional helper line shown below the drop zone while it's empty. */\n helperText = input<string | null>(null);\n /** Label for the optional link appended to `helperText`. */\n helperLinkText = input<string | null>(null);\n /** URL for the optional link appended to `helperText`. */\n helperLinkUrl = input<string | null>(null);\n /** Everything this instance needs to run its flow — see `UploadFlowConfig`. */\n config = input.required<UploadFlowConfig<T, C>>();\n /**\n * Terminal \"existing file\" card shown instead of the idle dropzone while\n * the queue is empty (e.g. edit mode: an already-loaded entity) — see\n * `LoaderPlaceholder`.\n */\n placeholder = input<LoaderPlaceholder<unknown> | null>(null);\n /**\n * Ids the consumer is currently waiting on its own confirmation for (see\n * `removeRequested`). Matching cards disable their remove button so the\n * user can't double-trigger a request while a decision is pending — this\n * component still has no opinion on what that confirmation looks like.\n */\n pendingRemovalIds = input<readonly string[]>([]);\n /**\n * Tooltip/accessible label for a real queue item's remove button — `tk-uploader` has no\n * copy of its own (same reasoning as `UploadFlowConfig.resolveText`), so the button stays\n * unlabeled unless the consumer supplies text here.\n */\n removeLabel = input<string>();\n /** Tooltip/accessible label for the `placeholder` card's trailing (re-upload) button. */\n placeholderReplaceLabel = input<string>();\n\n /** Emitted with the raw `File`(s) as soon as they're picked/dropped — `File[]` when `multiple`, a single `File` otherwise. */\n fileSelected = output<File | File[]>();\n /**\n * Emitted when a file-card's remove button is clicked — `tk-uploader` never\n * removes the item itself. Inspect `phase` to decide whether to confirm\n * (typically for `in-progress`) before calling\n * `UploaderQueueService.removeFromQueue(id)`.\n */\n removeRequested = output<UploaderRemoveRequest>();\n /**\n * Emitted when an item's `tk-process-steps` countdown (`stepsCountdownSeconds`)\n * reaches zero — `tk-uploader` never acts on it itself (doesn't remove the\n * item, doesn't close anything). The consumer decides what that means: close\n * a modal, remove the item, show a toast, etc.\n */\n stepsCountdownFinished = output<string>();\n\n protected fileInput =\n viewChild.required<ElementRef<HTMLInputElement>>('fileInput');\n protected queue = this.queueService.uploadQueue;\n protected isDragging = signal(false);\n\n /**\n * Files already in a terminal state (`success` / `error` / `invalid`) are\n * done — they don't consume capacity anymore even though they stay visible\n * in the queue until manually removed. Capacity is about what's still\n * in-flight, not the size of the visible history.\n */\n private readonly activeCount = computed(\n () => this.queue().filter((item) => !TERMINAL_STATUSES.has(item.status)).length\n );\n\n public isAtCapacity = computed(() => !this.multiple() && this.activeCount() >= 1);\n\n /**\n * Native `accept` attribute for the hidden `<input type=\"file\">`, derived\n * from `config.restrictions` (`rules[].extensions` or `allowedExtensions`)\n * — the same list that actually validates a file — so there is a single\n * source of truth instead of a separate, independently-settable input that\n * could drift out of sync with it. This is only a hint for the OS file\n * picker: it does not filter drag & drop and does not validate anything.\n */\n protected accept = computed(() => {\n const restrictions = this.config().restrictions;\n if (!restrictions) {\n return '';\n }\n const extensions = restrictions.rules?.length\n ? restrictions.rules.flatMap((rule) => rule.extensions)\n : restrictions.allowedExtensions;\n return extensions?.join(',') ?? '';\n });\n\n private dragCounter = 0;\n\n onDragOver(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n }\n\n onDragEnter(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter++;\n this.isDragging.set(true);\n }\n\n onDragLeave(event: DragEvent): void {\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter--;\n if (this.dragCounter === 0) {\n this.isDragging.set(false);\n }\n }\n\n onDrop(event: DragEvent): void {\n if (this.isAtCapacity()) {\n return;\n }\n event.preventDefault();\n event.stopPropagation();\n this.dragCounter = 0;\n this.isDragging.set(false);\n\n if (event.dataTransfer?.files) {\n this.handleFiles(event.dataTransfer.files);\n }\n }\n\n onFileChange(event: Event): void {\n if (this.isAtCapacity()) {\n return;\n }\n const input = event.target as HTMLInputElement;\n if (input.files) {\n this.handleFiles(input.files);\n }\n }\n\n onCancelItem(id: string): void {\n const item = this.queue().find((i) => i.id === id);\n if (!item) {\n return;\n }\n this.removeRequested.emit({ id, phase: resolveRemovePhase(item.status) });\n }\n\n protected isPendingRemoval(id: string): boolean {\n return this.pendingRemovalIds().includes(id);\n }\n\n protected stepsTitleFor(stepsTitle: string | undefined): string {\n return stepsTitle ?? DEFAULT_STEPS_TITLE;\n }\n\n /** Opens the OS file picker programmatically — a no-op while `isAtCapacity()`. */\n public triggerBrowse(): void {\n if (this.isAtCapacity()) {\n return;\n }\n this.fileInput().nativeElement.click();\n }\n\n private handleFiles(fileList: FileList): void {\n const allFiles = Array.from(fileList);\n if (allFiles.length === 0) {\n return;\n }\n\n const files = this.multiple() ? allFiles : allFiles.slice(0, 1);\n this.queueService.addToQueue(files, this.config());\n this.emitFileSelection(files);\n }\n\n private emitFileSelection(files: File[]): void {\n if (this.multiple()) {\n this.fileSelected.emit(files);\n } else {\n this.fileSelected.emit(files[0]);\n }\n }\n}\n","<div\n class=\"tk-uploader\"\n [class.tk-uploader--dragging]=\"isDragging()\"\n [class.tk-uploader--has-file]=\"queue().length > 0 || !!placeholder()\"\n [class.tk-uploader--disabled]=\"isAtCapacity()\"\n (dragover)=\"onDragOver($event)\"\n (dragenter)=\"onDragEnter($event)\"\n (dragleave)=\"onDragLeave($event)\"\n (drop)=\"onDrop($event)\">\n <input\n #fileInput\n type=\"file\"\n [accept]=\"accept()\"\n [multiple]=\"multiple()\"\n (change)=\"onFileChange($event)\"\n hidden />\n\n @if (queue().length === 0) {\n @if (placeholder()) {\n <!-- Stays a div, not a button: tk-uploader-file-card renders its own trailing\n <button> (replace icon), and a <button> cannot contain another <button>. -->\n <div\n class=\"tk-uploader__placeholder\"\n [class.tk-uploader__placeholder--dragging]=\"isDragging()\"\n role=\"button\"\n tabindex=\"0\"\n (click)=\"fileInput.click()\"\n (keydown.enter)=\"fileInput.click()\"\n (keydown.space)=\"fileInput.click(); $event.preventDefault()\">\n <tk-uploader-file-card\n [title]=\"placeholder()!.title\"\n [status]=\"placeholder()!.status\"\n [statusText]=\"placeholder()!.statusText\"\n [progress]=\"placeholder()!.progress ?? 0\"\n [previewUrl]=\"placeholder()!.previewUrl\"\n trailingIcon=\"upload\"\n trailingSeverity=\"secondary\"\n [trailingLabel]=\"placeholderReplaceLabel()\"\n (dismissed)=\"fileInput.click()\" />\n </div>\n } @else {\n <!-- Native <button>, not a div with role=\"button\": no nested interactive\n children here, so the accessible, semantic element is the right fit. -->\n <button type=\"button\" class=\"tk-uploader__idle\" (click)=\"fileInput.click()\">\n <div class=\"tk-uploader__illustration\">\n <tk-icon icon=\"upload\" color=\"primary\" />\n </div>\n\n <div class=\"tk-uploader__text\">\n <h3 class=\"tk-uploader__title\">\n {{ title() }}\n </h3>\n <p class=\"tk-uploader__subtitle\">\n {{ subtitle() }}\n </p>\n </div>\n </button>\n }\n } @else {\n <div class=\"tk-uploader__list\">\n @for (item of queue(); track item.id) {\n <tk-uploader-file-card\n [title]=\"item.file.name\"\n [status]=\"item.status\"\n [statusText]=\"item.statusText\"\n [progress]=\"item.progress\"\n [previewUrl]=\"item.previewUrl\"\n [isPendingRemoval]=\"isPendingRemoval(item.id)\"\n [trailingLabel]=\"removeLabel()\"\n (dismissed)=\"onCancelItem(item.id)\" />\n\n <!-- Gated to !multiple: a step-by-step breakdown per item gets noisy with several\n files uploading at once, so multiple falls back to the plain progress bar even\n when checkStatus returns steps. See uploader.mdx \"Known limitations\". -->\n @if (!multiple() && item.steps) {\n <tk-process-steps\n [steps]=\"item.steps\"\n [title]=\"stepsTitleFor(item.stepsTitle)\"\n [description]=\"item.stepsDescription\"\n [status]=\"item.stepsStatus ?? 'progress'\"\n [showIcon]=\"false\"\n [compact]=\"true\"\n [countdownSeconds]=\"item.stepsCountdownSeconds\"\n [countdownLabel]=\"item.stepsCountdownLabel ?? 'Closing in {seconds}s…'\"\n (countdownFinished)=\"stepsCountdownFinished.emit(item.id)\" />\n }\n }\n </div>\n }\n</div>\n\n@if (queue().length === 0 && helperText()) {\n <div class=\"tk-uploader__helper\">\n <span>{{ helperText() }}</span>\n @if (helperLinkText() && helperLinkUrl()) {\n <a\n [href]=\"helperLinkUrl()\"\n target=\"_blank\"\n rel=\"noopener\"\n class=\"tk-uploader__helper-link\">\n {{ helperLinkText() }}\n </a>\n }\n </div>\n}\n","import { Injectable, signal } from '@angular/core';\nimport {\n IUploaderStore,\n UploadItem\n} from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderStore` — a plain in-memory signal, nothing persisted.\n * Registered by `provideUploader()` under `UPLOADER_STORE`; one instance per\n * `tk-uploader` (not `providedIn: 'root'`), so each gets its own queue.\n */\n@Injectable()\nexport class UploaderStore<T = unknown> implements IUploaderStore<T> {\n private readonly queue = signal<UploadItem<T>[]>([]);\n\n public readonly uploadQueue = this.queue.asReadonly();\n\n add(item: UploadItem<T>): void {\n this.queue.update((items) => [...items, item]);\n }\n\n update(id: string, updates: Partial<UploadItem<T>>): void {\n this.queue.update((items) =>\n items.map((item) => (item.id === id ? { ...item, ...updates } : item))\n );\n }\n\n remove(id: string): void {\n this.queue.update((items) => items.filter((item) => item.id !== id));\n }\n\n clear(): void {\n this.queue.set([]);\n }\n}\n","import { Injectable, resource, ResourceRef } from '@angular/core';\nimport { firstValueFrom, fromEvent } from 'rxjs';\nimport {\n MediaAnalysis,\n MediaMetadata,\n PreviewFrame\n} from '../types/uploader.types';\nimport { IUploaderPreviewProvider } from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderPreviewProvider` — generates a client-side preview/\n * metadata pass during `analyzing` (dimensions for images/video, duration\n * for audio/video, a downscaled preview frame), entirely in the browser\n * with no network call. Registered by `provideUploader()` under\n * `UPLOADER_PREVIEW_PROVIDER`.\n */\n@Injectable()\nexport class UploaderPreviewProvider implements IUploaderPreviewProvider {\n /** Kicks off the analysis as an Angular `resource()`, re-run if `file` changes identity. */\n generatePreview(file: File): ResourceRef<MediaAnalysis | undefined> {\n return resource({\n params: () => file,\n loader: ({ params: f }) => this.analyzeFile(f)\n });\n }\n\n private async analyzeFile(file: File): Promise<MediaAnalysis> {\n const type = this.normalizeMimeType(file);\n try {\n return await this.dispatchByType(file, type);\n } catch (error) {\n return this.createErrorResult(file, type, error);\n }\n }\n\n private dispatchByType(file: File, type: string): Promise<MediaAnalysis> {\n if (type.startsWith('image/')) {\n return this.processImageFile(file, type);\n }\n if (type.startsWith('video/')) {\n return this.processVideoFile(file, type);\n }\n if (type.startsWith('audio/')) {\n return this.processAudioFile(file, type);\n }\n return Promise.resolve(\n this.createAnalysisResult(file, type, { size: file.size })\n );\n }\n\n private createAnalysisResult(\n file: File,\n mimeType: string,\n metadata: Omit<MediaMetadata, 'mimeType'>,\n previews?: PreviewFrame\n ): MediaAnalysis {\n return {\n previewUrl: previews?.url || '',\n previewBase64: previews?.base64 || '',\n previewBlob: previews?.blob,\n analysisError: false,\n metadata: { ...metadata, mimeType }\n };\n }\n\n private createErrorResult(\n file: File,\n mimeType: string,\n error: unknown\n ): MediaAnalysis {\n return {\n previewUrl: '',\n previewBase64: '',\n previewBlob: undefined,\n analysisError: true,\n technicalError: this.resolveTechnicalError(mimeType),\n errorDetail: error,\n metadata: { size: file.size, mimeType }\n };\n }\n\n private resolveTechnicalError(mimeType: string): string {\n const errorMap: Record<string, string> = {\n 'image/': 'PROCESS_FAILED',\n 'video/': 'PROCESS_FAILED',\n 'audio/': 'PROCESS_FAILED'\n };\n return (\n Object.entries(errorMap).find(([key]) => mimeType.startsWith(key))?.[1] ||\n 'ANALYSIS_FAILED'\n );\n }\n\n private resolveMimeFromExtension(file: File): string | undefined {\n const extension = file.name.split('.').pop()?.toLowerCase();\n const mimeMap: Record<string, string> = {\n zip: 'application/zip',\n pdf: 'application/pdf',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n mp4: 'video/mp4',\n mp3: 'audio/mpeg'\n };\n\n return extension ? mimeMap[extension] : undefined;\n }\n\n private normalizeMimeType(file: File): string {\n const byExtension = this.resolveMimeFromExtension(file);\n if (byExtension) {\n return byExtension;\n }\n\n const type = file.type.toLowerCase();\n const isZipVariant =\n type === 'application/x-zip-compressed' ||\n type === 'application/zip-compressed';\n\n return isZipVariant ? 'application/zip' : type || 'application/octet-stream';\n }\n\n private async processImageFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const img = new Image();\n const objectUrl = URL.createObjectURL(file);\n img.src = objectUrl;\n try {\n await this.waitForReady(img, 'load');\n return await this.buildImageAnalysis(img, file, type);\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n }\n\n private async buildImageAnalysis(\n img: HTMLImageElement,\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const preview = await this.captureScaledFrame(\n img,\n img.naturalWidth,\n img.naturalHeight\n );\n return this.createAnalysisResult(\n file,\n type,\n this.buildImageMetadata(img, file),\n preview\n );\n }\n\n private buildImageMetadata(\n img: HTMLImageElement,\n file: File\n ): Omit<MediaMetadata, 'mimeType'> {\n return {\n width: img.naturalWidth,\n height: img.naturalHeight,\n aspectRatio: img.naturalWidth / img.naturalHeight,\n size: file.size\n };\n }\n\n private async processAudioFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const audio = new Audio();\n const objectUrl = URL.createObjectURL(file);\n audio.src = objectUrl;\n try {\n await this.waitForReady(audio, 'loadedmetadata');\n return this.createAnalysisResult(file, type, {\n durationMs: audio.duration * 1000,\n size: file.size\n });\n } finally {\n URL.revokeObjectURL(objectUrl);\n }\n }\n\n private async processVideoFile(\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const video = this.createVideoElement(file);\n try {\n await this.waitForReady(video, 'loadedmetadata');\n await this.seekToTime(video, 1);\n return await this.buildVideoAnalysis(video, file, type);\n } finally {\n URL.revokeObjectURL(video.src);\n }\n }\n\n private async buildVideoAnalysis(\n video: HTMLVideoElement,\n file: File,\n type: string\n ): Promise<MediaAnalysis> {\n const preview = await this.captureScaledFrame(\n video,\n video.videoWidth,\n video.videoHeight\n );\n return this.createAnalysisResult(\n file,\n type,\n this.buildVideoMetadata(video, file),\n preview\n );\n }\n\n private buildVideoMetadata(\n video: HTMLVideoElement,\n file: File\n ): Omit<MediaMetadata, 'mimeType'> {\n return {\n width: video.videoWidth,\n height: video.videoHeight,\n durationMs: video.duration * 1000,\n aspectRatio: video.videoWidth / video.videoHeight,\n size: file.size\n };\n }\n\n private createVideoElement(file: File): HTMLVideoElement {\n const video = document.createElement('video');\n video.muted = true;\n video.playsInline = true;\n video.src = URL.createObjectURL(file);\n return video;\n }\n\n private async captureScaledFrame(\n source: CanvasImageSource,\n naturalWidth: number,\n naturalHeight: number\n ): Promise<PreviewFrame> {\n const { width, height } = this.calculateDimensions(\n naturalWidth,\n naturalHeight\n );\n return this.capturePreviewFrame(source, width, height);\n }\n\n private async capturePreviewFrame(\n source: CanvasImageSource,\n width: number,\n height: number\n ): Promise<PreviewFrame> {\n const canvas = this.prepareCanvas(width, height);\n const ctx = canvas.getContext('2d');\n ctx?.drawImage(source, 0, 0, width, height);\n const base64 = canvas.toDataURL('image/jpeg', 0.8);\n const blob = (await new Promise<Blob | null>(resolve =>\n canvas.toBlob(resolve, 'image/jpeg', 0.8)\n ))!;\n const url = URL.createObjectURL(blob);\n return { url, blob, base64 };\n }\n\n private async waitForReady(\n target: EventTarget,\n readyEvent: string\n ): Promise<void> {\n await Promise.race([\n firstValueFrom(fromEvent(target, readyEvent)),\n firstValueFrom(fromEvent(target, 'error')).then(() => {\n throw new Error('PROCESS_FAILED');\n })\n ]);\n }\n\n private seekToTime(video: HTMLVideoElement, seconds: number): Promise<Event> {\n video.currentTime = seconds;\n return firstValueFrom(fromEvent(video, 'seeked'));\n }\n\n private prepareCanvas(width: number, height: number): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n return canvas;\n }\n\n private calculateDimensions(\n originalWidth: number,\n originalHeight: number,\n maxSize = 400\n ): { width: number; height: number } {\n if (originalWidth <= maxSize && originalHeight <= maxSize) {\n return { width: originalWidth, height: originalHeight };\n }\n\n const ratio = originalWidth / originalHeight;\n if (originalWidth > originalHeight) {\n return { width: maxSize, height: maxSize / ratio };\n }\n return { width: maxSize * ratio, height: maxSize };\n }\n}\n","import {\n HttpBackend,\n HttpClient,\n HttpEvent,\n HttpEventType\n} from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { map, Observable } from 'rxjs';\nimport { IUploaderTransport } from '../types/uploader-item.types';\n\n/**\n * Default `IUploaderTransport` — a bare `HttpClient` (via `HttpBackend`, so\n * it bypasses app-level interceptors) that reports upload progress as a\n * plain 0-100 number. Registered by `provideUploader()` under\n * `UPLOADER_TRANSPORT`, for the consumer's own `steps`/`multipart.uploadPart`\n * functions to `inject()` — `tk-uploader` never calls this itself.\n */\n@Injectable()\nexport class TkUploadTransportService implements IUploaderTransport {\n private readonly handler = inject(HttpBackend);\n private readonly http = new HttpClient(this.handler);\n\n upload(\n url: string,\n file: File | Blob,\n method: 'PUT' | 'POST' = 'PUT',\n headers: Record<string, string | string[]> | null = {},\n reportProgress = true,\n observe: 'events' | 'body' = 'events',\n withCredentials = false\n ): Observable<unknown> {\n const finalHeaders = this.resolveHeaders(headers ?? {}, file);\n\n if (observe === 'body') {\n return this.http.request(method, url, {\n body: file,\n headers: finalHeaders,\n reportProgress,\n observe: 'body',\n withCredentials\n });\n }\n\n return this.http\n .request(method, url, {\n body: file,\n headers: finalHeaders,\n reportProgress,\n observe: 'events',\n withCredentials\n })\n .pipe(map((event: HttpEvent<unknown>) => this.mapUploadEvent(event)));\n }\n\n /**\n * Merges the caller's headers with a normalized `Content-Type`\n * (defaulting `.zip`-flavored mime types to `application/zip`).\n * @private\n */\n private resolveHeaders(\n headers: Record<string, string | string[]>,\n file: File | Blob\n ): Record<string, string | string[]> {\n const finalHeaders = { ...headers };\n const contentType = this.resolveContentType(headers, file);\n\n if (contentType) {\n finalHeaders['Content-Type'] = contentType;\n delete finalHeaders['content-type'];\n }\n return finalHeaders;\n }\n\n /**\n * @private\n */\n private resolveContentType(\n headers: Record<string, string | string[]>,\n file: File | Blob\n ): string {\n const contentType =\n this.headerValue(headers['Content-Type']) ||\n this.headerValue(headers['content-type']) ||\n file.type ||\n '';\n const fileName = file instanceof File ? file.name : '';\n const isZip =\n fileName.toLowerCase().endsWith('.zip') ||\n contentType === 'application/x-zip-compressed' ||\n contentType === 'application/zip-compressed';\n\n return isZip ? 'application/zip' : contentType;\n }\n\n /**\n * @private\n */\n private headerValue(value: string | string[] | undefined): string {\n return Array.isArray(value) ? value.join(',') : (value ?? '');\n }\n\n /**\n * @private\n */\n private mapUploadEvent(event: HttpEvent<unknown>): number {\n switch (event.type) {\n case HttpEventType.UploadProgress:\n return Math.round((100 * event.loaded) / (event.total || 1));\n case HttpEventType.Response:\n return 100;\n default:\n return 0;\n }\n }\n}\n","import { Provider } from '@angular/core';\nimport {\n UPLOADER_STORE,\n UPLOADER_PREVIEW_PROVIDER,\n UPLOADER_TRANSPORT\n} from '../tokens/uploader.tokens';\nimport { UploaderStore } from './uploader-store.service';\nimport { UploaderPreviewProvider } from './uploader-preview.service';\nimport { TkUploadTransportService } from './upload-transport.service';\nimport { UploaderQueueService } from './uploader-queue.service';\n\n/**\n * Registers every service `tk-uploader` depends on (queue, preview,\n * transport) — add to the `providers` of the component that hosts\n * `tk-uploader` (or a parent). Each instance gets its own queue.\n */\nexport function provideUploader(): Provider[] {\n return [\n UploaderStore,\n { provide: UPLOADER_STORE, useExisting: UploaderStore },\n UploaderPreviewProvider,\n { provide: UPLOADER_PREVIEW_PROVIDER, useExisting: UploaderPreviewProvider },\n TkUploadTransportService,\n { provide: UPLOADER_TRANSPORT, useExisting: TkUploadTransportService },\n UploaderQueueService\n ];\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tekus/design-system",
|
|
3
3
|
"description": "Tekus design system library",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.36.0",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"peerDependencies": {
|
|
7
7
|
"@angular/core": "^21.0.0",
|
|
@@ -68,6 +68,10 @@
|
|
|
68
68
|
"types": "./types/tekus-design-system-components-card-list.d.ts",
|
|
69
69
|
"default": "./fesm2022/tekus-design-system-components-card-list.mjs"
|
|
70
70
|
},
|
|
71
|
+
"./components/carousel": {
|
|
72
|
+
"types": "./types/tekus-design-system-components-carousel.d.ts",
|
|
73
|
+
"default": "./fesm2022/tekus-design-system-components-carousel.mjs"
|
|
74
|
+
},
|
|
71
75
|
"./components/checkbox": {
|
|
72
76
|
"types": "./types/tekus-design-system-components-checkbox.d.ts",
|
|
73
77
|
"default": "./fesm2022/tekus-design-system-components-checkbox.mjs"
|
|
@@ -96,6 +100,10 @@
|
|
|
96
100
|
"types": "./types/tekus-design-system-components-fallback-view.d.ts",
|
|
97
101
|
"default": "./fesm2022/tekus-design-system-components-fallback-view.mjs"
|
|
98
102
|
},
|
|
103
|
+
"./components/header": {
|
|
104
|
+
"types": "./types/tekus-design-system-components-header.d.ts",
|
|
105
|
+
"default": "./fesm2022/tekus-design-system-components-header.mjs"
|
|
106
|
+
},
|
|
99
107
|
"./components/icon": {
|
|
100
108
|
"types": "./types/tekus-design-system-components-icon.d.ts",
|
|
101
109
|
"default": "./fesm2022/tekus-design-system-components-icon.mjs"
|
|
@@ -136,6 +144,10 @@
|
|
|
136
144
|
"types": "./types/tekus-design-system-components-panel-menu.d.ts",
|
|
137
145
|
"default": "./fesm2022/tekus-design-system-components-panel-menu.mjs"
|
|
138
146
|
},
|
|
147
|
+
"./components/process-steps": {
|
|
148
|
+
"types": "./types/tekus-design-system-components-process-steps.d.ts",
|
|
149
|
+
"default": "./fesm2022/tekus-design-system-components-process-steps.mjs"
|
|
150
|
+
},
|
|
139
151
|
"./components/progress-bar": {
|
|
140
152
|
"types": "./types/tekus-design-system-components-progress-bar.d.ts",
|
|
141
153
|
"default": "./fesm2022/tekus-design-system-components-progress-bar.mjs"
|
|
@@ -204,6 +216,10 @@
|
|
|
204
216
|
"types": "./types/tekus-design-system-components-topbar.d.ts",
|
|
205
217
|
"default": "./fesm2022/tekus-design-system-components-topbar.mjs"
|
|
206
218
|
},
|
|
219
|
+
"./components/uploader": {
|
|
220
|
+
"types": "./types/tekus-design-system-components-uploader.d.ts",
|
|
221
|
+
"default": "./fesm2022/tekus-design-system-components-uploader.mjs"
|
|
222
|
+
},
|
|
207
223
|
"./core": {
|
|
208
224
|
"types": "./types/tekus-design-system-core.d.ts",
|
|
209
225
|
"default": "./fesm2022/tekus-design-system-core.mjs"
|
|
@@ -123,6 +123,25 @@ declare class ButtonComponent {
|
|
|
123
123
|
* @default `undefined`
|
|
124
124
|
*/
|
|
125
125
|
tooltipText: _angular_core.InputSignal<string | undefined>;
|
|
126
|
+
/**
|
|
127
|
+
* @property {boolean} full
|
|
128
|
+
* @description
|
|
129
|
+
* When true, the button stretches to fill the full width of its container.
|
|
130
|
+
* Unlike `size`, which scales typography and padding, this only affects
|
|
131
|
+
* how much horizontal space the button occupies.
|
|
132
|
+
*
|
|
133
|
+
* @default `false`
|
|
134
|
+
*/
|
|
135
|
+
full: _angular_core.InputSignal<boolean>;
|
|
136
|
+
/**
|
|
137
|
+
* @property {string} ariaLabel
|
|
138
|
+
* @description
|
|
139
|
+
* Accessible label forwarded to the native button. Required for
|
|
140
|
+
* icon-only buttons, where there is no visible label to announce.
|
|
141
|
+
*
|
|
142
|
+
* @default `undefined`
|
|
143
|
+
*/
|
|
144
|
+
ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
126
145
|
/**
|
|
127
146
|
* @property {'small' | 'large' | undefined} size
|
|
128
147
|
* @description
|
|
@@ -142,7 +161,7 @@ declare class ButtonComponent {
|
|
|
142
161
|
*/
|
|
143
162
|
onButtonClick(): void;
|
|
144
163
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<ButtonComponent, never>;
|
|
145
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ButtonComponent, "tk-button", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "severity": { "alias": "severity"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "link": { "alias": "link"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "tooltipText": { "alias": "tooltipText"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, never, true, never>;
|
|
164
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<ButtonComponent, "tk-button", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "severity": { "alias": "severity"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "link": { "alias": "link"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconPosition": { "alias": "iconPosition"; "required": false; "isSignal": true; }; "tooltipText": { "alias": "tooltipText"; "required": false; "isSignal": true; }; "full": { "alias": "full"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, never, true, never>;
|
|
146
165
|
}
|
|
147
166
|
|
|
148
167
|
export { ButtonComponent };
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { Carousel, CarouselPageEvent } from 'primeng/carousel';
|
|
3
|
+
import { TagSeverity } from '@tekus/design-system/components/tag';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Behavioral preset of the carousel. The rotation is always an infinite
|
|
7
|
+
* loop: after the last slide, next returns to the first one.
|
|
8
|
+
* - `'manual'`: the user navigates with arrows and indicator; failed slide
|
|
9
|
+
* images show an error fallback in place.
|
|
10
|
+
* - `'autoplay'`: the rotation advances automatically every 7 seconds with
|
|
11
|
+
* swipe gestures enabled; failed slide images remove the slide from the
|
|
12
|
+
* rotation without any error message (unattended usage).
|
|
13
|
+
*/
|
|
14
|
+
type CarouselVariant = 'manual' | 'autoplay';
|
|
15
|
+
/**
|
|
16
|
+
* Type of position indicator rendered by the carousel.
|
|
17
|
+
* - `'dots'`: dot indicators overlaid at the bottom of the slide.
|
|
18
|
+
* - `'thumbnails'`: clickable image thumbnails rendered below the slide.
|
|
19
|
+
*/
|
|
20
|
+
type CarouselIndicatorType = 'dots' | 'thumbnails';
|
|
21
|
+
/**
|
|
22
|
+
* Presentation state of a slide.
|
|
23
|
+
* - `'default'`: regular slide with image and content.
|
|
24
|
+
* - `'error'`: error view rendered with `tk-fallback-view`.
|
|
25
|
+
*
|
|
26
|
+
* Independently of this consumer-driven state, a slide whose image fails to
|
|
27
|
+
* load is switched to the error view automatically.
|
|
28
|
+
*/
|
|
29
|
+
type CarouselSlideState = 'default' | 'error';
|
|
30
|
+
/**
|
|
31
|
+
* Tag displayed over a slide, with an optional color scheme.
|
|
32
|
+
* The severity accepts the same values as `tk-tag`
|
|
33
|
+
* (`'primary' | 'secondary' | 'success' | 'info' | 'warn' | 'danger' | 'contrast'`).
|
|
34
|
+
*/
|
|
35
|
+
interface CarouselSlideTag {
|
|
36
|
+
/** Text of the tag. */
|
|
37
|
+
value: string;
|
|
38
|
+
/**
|
|
39
|
+
* Color scheme of the tag, forwarded to `tk-tag`.
|
|
40
|
+
* @default 'primary'
|
|
41
|
+
*/
|
|
42
|
+
severity?: TagSeverity;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Data contract for a single carousel slide.
|
|
46
|
+
*/
|
|
47
|
+
interface CarouselSlide {
|
|
48
|
+
/** Stable unique identifier, used for tracking and error handling. */
|
|
49
|
+
id: string | number;
|
|
50
|
+
/** URL of the slide background image. When omitted, the content is rendered over a dark background. */
|
|
51
|
+
imageSrc?: string;
|
|
52
|
+
/** Alternative text for the background image. Falls back to `title`. */
|
|
53
|
+
imageAlt?: string;
|
|
54
|
+
/** Main heading displayed over the image. */
|
|
55
|
+
title: string;
|
|
56
|
+
/** Supporting text displayed below the title. */
|
|
57
|
+
description?: string;
|
|
58
|
+
/**
|
|
59
|
+
* Short labels displayed above the title. Only the first two are rendered.
|
|
60
|
+
* Plain strings render with the default color scheme; use `CarouselSlideTag`
|
|
61
|
+
* objects to set a severity per tag.
|
|
62
|
+
*/
|
|
63
|
+
tags?: (string | CarouselSlideTag)[];
|
|
64
|
+
/** Label of the call-to-action button. When omitted, no button is rendered. */
|
|
65
|
+
actionLabel?: string;
|
|
66
|
+
/** Icon name (from the design system IconCatalog) shown in the action button. */
|
|
67
|
+
actionIcon?: string;
|
|
68
|
+
/**
|
|
69
|
+
* Consumer-driven presentation state of the slide.
|
|
70
|
+
* @default 'default'
|
|
71
|
+
*/
|
|
72
|
+
state?: CarouselSlideState;
|
|
73
|
+
/** Illustration URL for the error view, forwarded to `tk-fallback-view`. */
|
|
74
|
+
errorImageSrc?: string;
|
|
75
|
+
/** Title of the error view (manual variant only). */
|
|
76
|
+
errorTitle?: string;
|
|
77
|
+
/** Message of the error view (manual variant only). */
|
|
78
|
+
errorDescription?: string;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Payload emitted when the active slide changes.
|
|
82
|
+
*/
|
|
83
|
+
interface CarouselSlideChangeEvent {
|
|
84
|
+
/** Zero-based index of the active slide within the visible slides. */
|
|
85
|
+
index: number;
|
|
86
|
+
/** The slide that became active. */
|
|
87
|
+
slide: CarouselSlide;
|
|
88
|
+
}
|
|
89
|
+
/** Autoplay interval, in milliseconds, applied by the autoplay variant. */
|
|
90
|
+
declare const AUTOPLAY_INTERVAL_MS = 7000;
|
|
91
|
+
/** Maximum number of tags rendered per slide. */
|
|
92
|
+
declare const MAX_VISIBLE_TAGS = 2;
|
|
93
|
+
/** Maximum number of characters of the slide title before truncation. */
|
|
94
|
+
declare const MAX_TITLE_LENGTH = 50;
|
|
95
|
+
/** Maximum number of characters of the slide description before truncation. */
|
|
96
|
+
declare const MAX_DESCRIPTION_LENGTH = 140;
|
|
97
|
+
/** Maximum number of characters per tag before truncation. */
|
|
98
|
+
declare const MAX_TAG_LENGTH = 20;
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @component CarouselComponent
|
|
102
|
+
* @description
|
|
103
|
+
* Adaptive carousel that displays a sequence of slides one at a time, each
|
|
104
|
+
* with a background image, up to two tags, a title, a description, and an
|
|
105
|
+
* optional call-to-action button. It wraps PrimeNG's `p-carousel` with the
|
|
106
|
+
* Tekus design system look.
|
|
107
|
+
*
|
|
108
|
+
* The rotation is always an infinite loop: after the last slide, next returns
|
|
109
|
+
* to the first one.
|
|
110
|
+
*
|
|
111
|
+
* Variants (`variant` input):
|
|
112
|
+
* - `'manual'` (default): the user navigates with arrows and indicator; if a
|
|
113
|
+
* slide image fails to load, an error fallback is shown in its place.
|
|
114
|
+
* - `'autoplay'`: the rotation advances automatically every 7 seconds with
|
|
115
|
+
* swipe gestures enabled; slides whose image fails to load are removed
|
|
116
|
+
* from the rotation silently (unattended usage).
|
|
117
|
+
*
|
|
118
|
+
* Indicators (`indicator` input):
|
|
119
|
+
* - `'dots'` (default): dot indicators overlaid at the bottom of the slide.
|
|
120
|
+
* - `'thumbnails'`: clickable image thumbnails rendered below the slide.
|
|
121
|
+
*
|
|
122
|
+
* The slide height can be customized with the `--tk-carousel-height` CSS
|
|
123
|
+
* variable (defaults to `28.125rem`).
|
|
124
|
+
*
|
|
125
|
+
* @usage
|
|
126
|
+
* ### Manual navigation (default)
|
|
127
|
+
* ```html
|
|
128
|
+
* <tk-carousel
|
|
129
|
+
* [slides]="slides"
|
|
130
|
+
* (slideChange)="onSlideChange($event)"
|
|
131
|
+
* (actionClick)="onActionClick($event)"
|
|
132
|
+
* (slideClick)="openLightbox($event)">
|
|
133
|
+
* </tk-carousel>
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* ### Autoplay with thumbnails
|
|
137
|
+
* ```html
|
|
138
|
+
* <tk-carousel
|
|
139
|
+
* [slides]="slides"
|
|
140
|
+
* variant="autoplay"
|
|
141
|
+
* indicator="thumbnails">
|
|
142
|
+
* </tk-carousel>
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
declare class CarouselComponent {
|
|
146
|
+
/** Slides to display. Each slide must have a stable unique `id`. */
|
|
147
|
+
slides: _angular_core.InputSignal<CarouselSlide[]>;
|
|
148
|
+
/**
|
|
149
|
+
* Behavioral preset of the carousel.
|
|
150
|
+
* @default 'manual'
|
|
151
|
+
*/
|
|
152
|
+
variant: _angular_core.InputSignal<CarouselVariant>;
|
|
153
|
+
/**
|
|
154
|
+
* Type of position indicator.
|
|
155
|
+
* @default 'dots'
|
|
156
|
+
*/
|
|
157
|
+
indicator: _angular_core.InputSignal<CarouselIndicatorType>;
|
|
158
|
+
/** Emits when the active slide changes, via arrows, indicator, swipe, or autoplay. */
|
|
159
|
+
slideChange: _angular_core.OutputEmitterRef<CarouselSlideChangeEvent>;
|
|
160
|
+
/** Emits the slide whose call-to-action button was clicked. */
|
|
161
|
+
actionClick: _angular_core.OutputEmitterRef<CarouselSlide>;
|
|
162
|
+
/** Emits the slide whose image was clicked, so consumers can open a lightbox. */
|
|
163
|
+
slideClick: _angular_core.OutputEmitterRef<CarouselSlide>;
|
|
164
|
+
/** Reference to the underlying PrimeNG carousel, used for thumbnail navigation. */
|
|
165
|
+
primeCarousel: _angular_core.Signal<Carousel | undefined>;
|
|
166
|
+
/** Zero-based index of the active slide within the visible slides. */
|
|
167
|
+
currentIndex: _angular_core.WritableSignal<number>;
|
|
168
|
+
/** Ids of the slides whose image failed to load. */
|
|
169
|
+
failedSlideIds: _angular_core.WritableSignal<ReadonlySet<string | number>>;
|
|
170
|
+
/** Whether the autoplay preset is active. */
|
|
171
|
+
isAutoplay: _angular_core.Signal<boolean>;
|
|
172
|
+
/** Autoplay interval mapped from the variant preset. `0` disables autoplay. */
|
|
173
|
+
autoplayInterval: _angular_core.Signal<7000 | 0>;
|
|
174
|
+
/**
|
|
175
|
+
* Slides currently part of the rotation. The autoplay variant excludes
|
|
176
|
+
* slides whose image failed to load; the manual variant keeps them and
|
|
177
|
+
* shows an error fallback instead.
|
|
178
|
+
*/
|
|
179
|
+
visibleSlides: _angular_core.Signal<CarouselSlide[]>;
|
|
180
|
+
/**
|
|
181
|
+
* Whether the navigation controls (arrows and indicators) are rendered.
|
|
182
|
+
* With a single visible slide there is nowhere to navigate, so they are hidden.
|
|
183
|
+
*/
|
|
184
|
+
showNavigation: _angular_core.Signal<boolean>;
|
|
185
|
+
/** Whether the dot indicator is rendered. */
|
|
186
|
+
showDots: _angular_core.Signal<boolean>;
|
|
187
|
+
/** Whether the thumbnail indicator is rendered. */
|
|
188
|
+
showThumbnails: _angular_core.Signal<boolean>;
|
|
189
|
+
onPage(event: CarouselPageEvent): void;
|
|
190
|
+
onThumbnailClick(event: MouseEvent, index: number): void;
|
|
191
|
+
onImageError(slide: CarouselSlide): void;
|
|
192
|
+
onActionClick(slide: CarouselSlide): void;
|
|
193
|
+
onSlideClick(slide: CarouselSlide): void;
|
|
194
|
+
hasSlideError(slide: CarouselSlide): boolean;
|
|
195
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<CarouselComponent, never>;
|
|
196
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<CarouselComponent, "tk-carousel", never, { "slides": { "alias": "slides"; "required": true; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "indicator": { "alias": "indicator"; "required": false; "isSignal": true; }; }, { "slideChange": "slideChange"; "actionClick": "actionClick"; "slideClick": "slideClick"; }, never, never, true, never>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export { AUTOPLAY_INTERVAL_MS, CarouselComponent, MAX_DESCRIPTION_LENGTH, MAX_TAG_LENGTH, MAX_TITLE_LENGTH, MAX_VISIBLE_TAGS };
|
|
200
|
+
export type { CarouselIndicatorType, CarouselSlide, CarouselSlideChangeEvent, CarouselSlideState, CarouselSlideTag, CarouselVariant };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as _angular_core from '@angular/core';
|
|
2
|
+
import { MenuItem } from 'primeng/api';
|
|
3
|
+
|
|
4
|
+
interface TkHeaderAction {
|
|
5
|
+
icon: string;
|
|
6
|
+
label: string;
|
|
7
|
+
action: () => void;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface TkHeaderDropdownAction {
|
|
11
|
+
type: 'dropdown';
|
|
12
|
+
model: MenuItem[];
|
|
13
|
+
icon?: string;
|
|
14
|
+
label?: string;
|
|
15
|
+
iconPosition?: 'left' | 'right';
|
|
16
|
+
size?: 'small' | 'large';
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
tooltip?: string;
|
|
19
|
+
}
|
|
20
|
+
type TkHeaderAnyAction = TkHeaderAction | TkHeaderDropdownAction;
|
|
21
|
+
|
|
22
|
+
declare class HeaderComponent {
|
|
23
|
+
logoSrc: _angular_core.InputSignal<string | undefined>;
|
|
24
|
+
logoAlt: _angular_core.InputSignal<string>;
|
|
25
|
+
leftActions: _angular_core.InputSignal<TkHeaderAnyAction[]>;
|
|
26
|
+
rightActions: _angular_core.InputSignal<TkHeaderAnyAction[]>;
|
|
27
|
+
protected isDropdown(action: TkHeaderAnyAction): action is TkHeaderDropdownAction;
|
|
28
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<HeaderComponent, never>;
|
|
29
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<HeaderComponent, "tk-header", never, { "logoSrc": { "alias": "logoSrc"; "required": false; "isSignal": true; }; "logoAlt": { "alias": "logoAlt"; "required": false; "isSignal": true; }; "leftActions": { "alias": "leftActions"; "required": false; "isSignal": true; }; "rightActions": { "alias": "rightActions"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { HeaderComponent };
|
|
33
|
+
export type { TkHeaderAction, TkHeaderAnyAction, TkHeaderDropdownAction };
|