codexly-ui 0.4.9 → 0.5.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/codexly-ui.mjs +97 -30
- package/fesm2022/codexly-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/codexly-ui.d.ts +29 -3
package/fesm2022/codexly-ui.mjs
CHANGED
|
@@ -4920,6 +4920,9 @@ function resolveFileTypeVisual(name, mimeType) {
|
|
|
4920
4920
|
return FILE_TYPE_BY_EXTENSION[ext] ?? FILE_TYPE_DEFAULT;
|
|
4921
4921
|
}
|
|
4922
4922
|
|
|
4923
|
+
const DEFAULT_PRIMARY_ACTION = () => ({
|
|
4924
|
+
icon: 'close', color: 'red', tooltip: 'Eliminar',
|
|
4925
|
+
});
|
|
4923
4926
|
class ClxUploadComponent {
|
|
4924
4927
|
_themeSvc = inject(ClxThemeService);
|
|
4925
4928
|
// ── Inputs ─────────────────────────────────────────────────────────────────
|
|
@@ -4936,10 +4939,18 @@ class ClxUploadComponent {
|
|
|
4936
4939
|
* preview grid as newly-selected local files. The component never deletes these itself —
|
|
4937
4940
|
* removing one only emits `existingFileRemove`, letting the caller decide (e.g. call the API). */
|
|
4938
4941
|
existingFiles = input([], ...(ngDevMode ? [{ debugName: "existingFiles" }] : /* istanbul ignore next */ []));
|
|
4942
|
+
/** Resolves the badge button shown top-right on each thumbnail. Defaults to a red "Eliminar"
|
|
4943
|
+
* button wired to the built-in remove behavior. Return `null` for an item to hide it. */
|
|
4944
|
+
primaryAction = input(DEFAULT_PRIMARY_ACTION, ...(ngDevMode ? [{ debugName: "primaryAction" }] : /* istanbul ignore next */ []));
|
|
4945
|
+
/** Resolves an optional second badge button (bottom-right on each thumbnail). Hidden by
|
|
4946
|
+
* default — the caller owns what clicking it means (e.g. opening a settings modal); this
|
|
4947
|
+
* component only reports which item was clicked via `secondaryActionClick`. */
|
|
4948
|
+
secondaryAction = input(null, ...(ngDevMode ? [{ debugName: "secondaryAction" }] : /* istanbul ignore next */ []));
|
|
4939
4949
|
// ── Outputs ────────────────────────────────────────────────────────────────
|
|
4940
4950
|
onUploadError = output();
|
|
4941
4951
|
onUploadSuccess = output();
|
|
4942
4952
|
existingFileRemove = output();
|
|
4953
|
+
secondaryActionClick = output();
|
|
4943
4954
|
// ── Internal state ─────────────────────────────────────────────────────────
|
|
4944
4955
|
_files = signal([], ...(ngDevMode ? [{ debugName: "_files" }] : /* istanbul ignore next */ []));
|
|
4945
4956
|
_isDragging = signal(false, ...(ngDevMode ? [{ debugName: "_isDragging" }] : /* istanbul ignore next */ []));
|
|
@@ -5104,6 +5115,18 @@ class ClxUploadComponent {
|
|
|
5104
5115
|
if (files?.length)
|
|
5105
5116
|
this._addFiles(files);
|
|
5106
5117
|
}
|
|
5118
|
+
_resolvePrimaryAction(item) {
|
|
5119
|
+
return this.primaryAction()(item) ?? null;
|
|
5120
|
+
}
|
|
5121
|
+
_resolveSecondaryAction(item) {
|
|
5122
|
+
const resolver = this.secondaryAction();
|
|
5123
|
+
return resolver ? (resolver(item) ?? null) : null;
|
|
5124
|
+
}
|
|
5125
|
+
/** Built-in behavior for the default primary action (remove). Callers who override
|
|
5126
|
+
* `primaryAction` only for its visuals still get this same removal behavior. */
|
|
5127
|
+
_onPrimaryAction(item) {
|
|
5128
|
+
this._removeItem(item);
|
|
5129
|
+
}
|
|
5107
5130
|
_removeItem(item) {
|
|
5108
5131
|
if (item.kind === 'existing') {
|
|
5109
5132
|
this.existingFileRemove.emit(item.existing.id);
|
|
@@ -5217,7 +5240,7 @@ class ClxUploadComponent {
|
|
|
5217
5240
|
return `${(bytes / 1_048_576).toFixed(1)} MB`;
|
|
5218
5241
|
}
|
|
5219
5242
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxUploadComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
5220
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxUploadComponent, isStandalone: true, selector: "clx-upload", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, existingFiles: { classPropertyName: "existingFiles", publicName: "existingFiles", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadError: "onUploadError", onUploadSuccess: "onUploadSuccess", existingFileRemove: "existingFileRemove" }, host: { classAttribute: "block w-full" }, viewQueries: [{ propertyName: "_fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
5243
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.15", type: ClxUploadComponent, isStandalone: true, selector: "clx-upload", inputs: { multiple: { classPropertyName: "multiple", publicName: "multiple", isSignal: true, isRequired: false, transformFunction: null }, accept: { classPropertyName: "accept", publicName: "accept", isSignal: true, isRequired: false, transformFunction: null }, maxFileSize: { classPropertyName: "maxFileSize", publicName: "maxFileSize", isSignal: true, isRequired: false, transformFunction: null }, color: { classPropertyName: "color", publicName: "color", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, existingFiles: { classPropertyName: "existingFiles", publicName: "existingFiles", isSignal: true, isRequired: false, transformFunction: null }, primaryAction: { classPropertyName: "primaryAction", publicName: "primaryAction", isSignal: true, isRequired: false, transformFunction: null }, secondaryAction: { classPropertyName: "secondaryAction", publicName: "secondaryAction", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onUploadError: "onUploadError", onUploadSuccess: "onUploadSuccess", existingFileRemove: "existingFileRemove", secondaryActionClick: "secondaryActionClick" }, host: { classAttribute: "block w-full" }, viewQueries: [{ propertyName: "_fileInput", first: true, predicate: ["fileInput"], descendants: true, isSignal: true }], ngImport: i0, template: `
|
|
5221
5244
|
<!-- Hidden file input -->
|
|
5222
5245
|
<input
|
|
5223
5246
|
#fileInput
|
|
@@ -5286,19 +5309,41 @@ class ClxUploadComponent {
|
|
|
5286
5309
|
}
|
|
5287
5310
|
</div>
|
|
5288
5311
|
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
|
|
5295
|
-
|
|
5296
|
-
|
|
5297
|
-
|
|
5298
|
-
|
|
5299
|
-
|
|
5300
|
-
|
|
5301
|
-
|
|
5312
|
+
@let primaryAction = _resolvePrimaryAction(item);
|
|
5313
|
+
@if (primaryAction) {
|
|
5314
|
+
<button
|
|
5315
|
+
clx-button
|
|
5316
|
+
type="button"
|
|
5317
|
+
variant="solid"
|
|
5318
|
+
[color]="primaryAction.color ?? 'red'"
|
|
5319
|
+
shape="circle"
|
|
5320
|
+
size="xxs"
|
|
5321
|
+
[icon]="primaryAction.icon"
|
|
5322
|
+
[iconOnly]="true"
|
|
5323
|
+
[clxTooltip]="primaryAction.tooltip ?? ''"
|
|
5324
|
+
class="absolute top-0 right-0 -translate-y-1/2 translate-x-1/2 shadow-md z-10"
|
|
5325
|
+
[disabled]="_disabled()"
|
|
5326
|
+
(click)="_onPrimaryAction(item); $event.stopPropagation()">
|
|
5327
|
+
</button>
|
|
5328
|
+
}
|
|
5329
|
+
|
|
5330
|
+
@let secondaryAction = _resolveSecondaryAction(item);
|
|
5331
|
+
@if (secondaryAction) {
|
|
5332
|
+
<button
|
|
5333
|
+
clx-button
|
|
5334
|
+
type="button"
|
|
5335
|
+
variant="solid"
|
|
5336
|
+
[color]="secondaryAction.color ?? 'slate'"
|
|
5337
|
+
shape="circle"
|
|
5338
|
+
size="xxs"
|
|
5339
|
+
[icon]="secondaryAction.icon"
|
|
5340
|
+
[iconOnly]="true"
|
|
5341
|
+
[clxTooltip]="secondaryAction.tooltip ?? ''"
|
|
5342
|
+
class="absolute bottom-0 right-0 translate-y-1/2 translate-x-1/2 shadow-md z-10"
|
|
5343
|
+
[disabled]="_disabled()"
|
|
5344
|
+
(click)="secondaryActionClick.emit(item); $event.stopPropagation()">
|
|
5345
|
+
</button>
|
|
5346
|
+
}
|
|
5302
5347
|
|
|
5303
5348
|
<div class="px-1.5 py-1 w-full min-w-0">
|
|
5304
5349
|
<p class="text-[11px] leading-tight text-clx-text-label font-medium truncate" [title]="item.name">{{ item.name }}</p>
|
|
@@ -5318,14 +5363,14 @@ class ClxUploadComponent {
|
|
|
5318
5363
|
{{ _errorMessage() }}
|
|
5319
5364
|
</p>
|
|
5320
5365
|
}
|
|
5321
|
-
`, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "component", type: ClxButtonComponent, selector: "button[clx-button], a[clx-button]", inputs: ["variant", "color", "size", "shape", "loading", "disabled", "block", "icon", "iconPosition", "iconOnly", "badge", "badgeColor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5366
|
+
`, isInline: true, dependencies: [{ kind: "component", type: ClxIconComponent, selector: "span[clx-icon]", inputs: ["name", "size", "color", "fill"] }, { kind: "component", type: ClxButtonComponent, selector: "button[clx-button], a[clx-button]", inputs: ["variant", "color", "size", "shape", "loading", "disabled", "block", "icon", "iconPosition", "iconOnly", "badge", "badgeColor"] }, { kind: "directive", type: ClxTooltipDirective, selector: "[clxTooltip]", inputs: ["clxTooltip", "clxTooltipPosition", "clxTooltipColor", "clxTooltipSize", "clxTooltipDelay"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
5322
5367
|
}
|
|
5323
5368
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImport: i0, type: ClxUploadComponent, decorators: [{
|
|
5324
5369
|
type: Component,
|
|
5325
5370
|
args: [{
|
|
5326
5371
|
selector: 'clx-upload',
|
|
5327
5372
|
standalone: true,
|
|
5328
|
-
imports: [ClxIconComponent, ClxButtonComponent],
|
|
5373
|
+
imports: [ClxIconComponent, ClxButtonComponent, ClxTooltipDirective],
|
|
5329
5374
|
template: `
|
|
5330
5375
|
<!-- Hidden file input -->
|
|
5331
5376
|
<input
|
|
@@ -5395,19 +5440,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
5395
5440
|
}
|
|
5396
5441
|
</div>
|
|
5397
5442
|
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5443
|
+
@let primaryAction = _resolvePrimaryAction(item);
|
|
5444
|
+
@if (primaryAction) {
|
|
5445
|
+
<button
|
|
5446
|
+
clx-button
|
|
5447
|
+
type="button"
|
|
5448
|
+
variant="solid"
|
|
5449
|
+
[color]="primaryAction.color ?? 'red'"
|
|
5450
|
+
shape="circle"
|
|
5451
|
+
size="xxs"
|
|
5452
|
+
[icon]="primaryAction.icon"
|
|
5453
|
+
[iconOnly]="true"
|
|
5454
|
+
[clxTooltip]="primaryAction.tooltip ?? ''"
|
|
5455
|
+
class="absolute top-0 right-0 -translate-y-1/2 translate-x-1/2 shadow-md z-10"
|
|
5456
|
+
[disabled]="_disabled()"
|
|
5457
|
+
(click)="_onPrimaryAction(item); $event.stopPropagation()">
|
|
5458
|
+
</button>
|
|
5459
|
+
}
|
|
5460
|
+
|
|
5461
|
+
@let secondaryAction = _resolveSecondaryAction(item);
|
|
5462
|
+
@if (secondaryAction) {
|
|
5463
|
+
<button
|
|
5464
|
+
clx-button
|
|
5465
|
+
type="button"
|
|
5466
|
+
variant="solid"
|
|
5467
|
+
[color]="secondaryAction.color ?? 'slate'"
|
|
5468
|
+
shape="circle"
|
|
5469
|
+
size="xxs"
|
|
5470
|
+
[icon]="secondaryAction.icon"
|
|
5471
|
+
[iconOnly]="true"
|
|
5472
|
+
[clxTooltip]="secondaryAction.tooltip ?? ''"
|
|
5473
|
+
class="absolute bottom-0 right-0 translate-y-1/2 translate-x-1/2 shadow-md z-10"
|
|
5474
|
+
[disabled]="_disabled()"
|
|
5475
|
+
(click)="secondaryActionClick.emit(item); $event.stopPropagation()">
|
|
5476
|
+
</button>
|
|
5477
|
+
}
|
|
5411
5478
|
|
|
5412
5479
|
<div class="px-1.5 py-1 w-full min-w-0">
|
|
5413
5480
|
<p class="text-[11px] leading-tight text-clx-text-label font-medium truncate" [title]="item.name">{{ item.name }}</p>
|
|
@@ -5434,7 +5501,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.15", ngImpo
|
|
|
5434
5501
|
class: 'block w-full',
|
|
5435
5502
|
},
|
|
5436
5503
|
}]
|
|
5437
|
-
}], ctorParameters: () => [], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], existingFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFiles", required: false }] }], onUploadError: [{ type: i0.Output, args: ["onUploadError"] }], onUploadSuccess: [{ type: i0.Output, args: ["onUploadSuccess"] }], existingFileRemove: [{ type: i0.Output, args: ["existingFileRemove"] }], _fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
|
|
5504
|
+
}], ctorParameters: () => [], propDecorators: { multiple: [{ type: i0.Input, args: [{ isSignal: true, alias: "multiple", required: false }] }], accept: [{ type: i0.Input, args: [{ isSignal: true, alias: "accept", required: false }] }], maxFileSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxFileSize", required: false }] }], color: [{ type: i0.Input, args: [{ isSignal: true, alias: "color", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], existingFiles: [{ type: i0.Input, args: [{ isSignal: true, alias: "existingFiles", required: false }] }], primaryAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "primaryAction", required: false }] }], secondaryAction: [{ type: i0.Input, args: [{ isSignal: true, alias: "secondaryAction", required: false }] }], onUploadError: [{ type: i0.Output, args: ["onUploadError"] }], onUploadSuccess: [{ type: i0.Output, args: ["onUploadSuccess"] }], existingFileRemove: [{ type: i0.Output, args: ["existingFileRemove"] }], secondaryActionClick: [{ type: i0.Output, args: ["secondaryActionClick"] }], _fileInput: [{ type: i0.ViewChild, args: ['fileInput', { isSignal: true }] }] } });
|
|
5438
5505
|
|
|
5439
5506
|
const COLOR_PICKER_SIZE_MAP = {
|
|
5440
5507
|
sm: { minH: 'min-h-8', text: 'text-sm', label: 'text-xs font-medium', hint: 'text-xs', px: 'px-2.5', swatchSz: 'w-4 h-4', btnSize: 'xs' },
|