shirkasoft-ui-components 1.2.0 → 1.3.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/shirkasoft-ui-components-breadcrumb.mjs +199 -0
- package/fesm2022/shirkasoft-ui-components-breadcrumb.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-button.mjs +148 -0
- package/fesm2022/shirkasoft-ui-components-button.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-chart.mjs +153 -0
- package/fesm2022/shirkasoft-ui-components-chart.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs +143 -0
- package/fesm2022/shirkasoft-ui-components-confirm-dialog.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs +638 -0
- package/fesm2022/shirkasoft-ui-components-date-picker.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-fieldset.mjs +94 -0
- package/fesm2022/shirkasoft-ui-components-fieldset.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-file-upload.mjs +242 -0
- package/fesm2022/shirkasoft-ui-components-file-upload.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-knob.mjs +269 -0
- package/fesm2022/shirkasoft-ui-components-knob.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-loading.mjs +255 -0
- package/fesm2022/shirkasoft-ui-components-loading.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-modal.mjs +290 -0
- package/fesm2022/shirkasoft-ui-components-modal.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-notification.mjs +143 -0
- package/fesm2022/shirkasoft-ui-components-notification.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-price-input.mjs +64 -0
- package/fesm2022/shirkasoft-ui-components-price-input.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs +205 -0
- package/fesm2022/shirkasoft-ui-components-rail-sidebar.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-select.mjs +737 -0
- package/fesm2022/shirkasoft-ui-components-select.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-sidebar.mjs +185 -0
- package/fesm2022/shirkasoft-ui-components-sidebar.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-skeleton.mjs +74 -0
- package/fesm2022/shirkasoft-ui-components-skeleton.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-table.mjs +689 -0
- package/fesm2022/shirkasoft-ui-components-table.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-tabs.mjs +249 -0
- package/fesm2022/shirkasoft-ui-components-tabs.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-tag.mjs +70 -0
- package/fesm2022/shirkasoft-ui-components-tag.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-text-field.mjs +370 -0
- package/fesm2022/shirkasoft-ui-components-text-field.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-timeline.mjs +222 -0
- package/fesm2022/shirkasoft-ui-components-timeline.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-toggle.mjs +186 -0
- package/fesm2022/shirkasoft-ui-components-toggle.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-tooltip.mjs +169 -0
- package/fesm2022/shirkasoft-ui-components-tooltip.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-utils.mjs +64 -0
- package/fesm2022/shirkasoft-ui-components-utils.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components-wizard.mjs +167 -0
- package/fesm2022/shirkasoft-ui-components-wizard.mjs.map +1 -0
- package/fesm2022/shirkasoft-ui-components.mjs +0 -5729
- package/fesm2022/shirkasoft-ui-components.mjs.map +1 -1
- package/package.json +101 -1
- package/types/shirkasoft-ui-components-breadcrumb.d.ts +68 -0
- package/types/shirkasoft-ui-components-button.d.ts +59 -0
- package/types/shirkasoft-ui-components-chart.d.ts +65 -0
- package/types/shirkasoft-ui-components-confirm-dialog.d.ts +88 -0
- package/types/shirkasoft-ui-components-date-picker.d.ts +200 -0
- package/types/shirkasoft-ui-components-fieldset.d.ts +72 -0
- package/types/shirkasoft-ui-components-file-upload.d.ts +87 -0
- package/types/shirkasoft-ui-components-knob.d.ts +69 -0
- package/types/shirkasoft-ui-components-loading.d.ts +94 -0
- package/types/shirkasoft-ui-components-modal.d.ts +139 -0
- package/types/shirkasoft-ui-components-notification.d.ts +82 -0
- package/types/shirkasoft-ui-components-price-input.d.ts +41 -0
- package/types/shirkasoft-ui-components-rail-sidebar.d.ts +121 -0
- package/types/shirkasoft-ui-components-select.d.ts +182 -0
- package/types/shirkasoft-ui-components-sidebar.d.ts +106 -0
- package/types/shirkasoft-ui-components-skeleton.d.ts +36 -0
- package/types/shirkasoft-ui-components-table.d.ts +293 -0
- package/types/shirkasoft-ui-components-tabs.d.ts +102 -0
- package/types/shirkasoft-ui-components-tag.d.ts +31 -0
- package/types/shirkasoft-ui-components-text-field.d.ts +120 -0
- package/types/shirkasoft-ui-components-timeline.d.ts +178 -0
- package/types/shirkasoft-ui-components-toggle.d.ts +48 -0
- package/types/shirkasoft-ui-components-tooltip.d.ts +47 -0
- package/types/shirkasoft-ui-components-utils.d.ts +9 -0
- package/types/shirkasoft-ui-components-wizard.d.ts +101 -0
- package/types/shirkasoft-ui-components.d.ts +1 -2333
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { input, signal, output, ChangeDetectionStrategy, Component, inject, DestroyRef, ApplicationRef, EnvironmentInjector, createComponent, Injectable } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { LucideTriangleAlert, LucideDynamicIcon } from '@lucide/angular';
|
|
6
|
+
import { getIcon } from 'shirkasoft-ui-components/utils';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Shirkasoft UI Components.
|
|
10
|
+
* Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).
|
|
11
|
+
* Belongs to Shirkasoft.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Confirmation dialog opened via `show()` which resolves a Promise<boolean>
|
|
15
|
+
* with the user's choice.
|
|
16
|
+
*/
|
|
17
|
+
class ConfirmDialogComponent {
|
|
18
|
+
constructor() {
|
|
19
|
+
this.getIcon = (name) => getIcon(name, LucideTriangleAlert);
|
|
20
|
+
/** Title shown in the dialog header. */
|
|
21
|
+
this.title = input('Confirmar acción', ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
|
|
22
|
+
/** Message body of the dialog. */
|
|
23
|
+
this.message = input('¿Está seguro de realizar esta acción?', ...(ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []));
|
|
24
|
+
/** Label of the confirm button. */
|
|
25
|
+
this.confirmLabel = input('Confirmar', ...(ngDevMode ? [{ debugName: "confirmLabel" }] : /* istanbul ignore next */ []));
|
|
26
|
+
/** Label of the cancel button. */
|
|
27
|
+
this.cancelLabel = input('Cancelar', ...(ngDevMode ? [{ debugName: "cancelLabel" }] : /* istanbul ignore next */ []));
|
|
28
|
+
/** Text shown on the confirm button while `loading` is true. */
|
|
29
|
+
this.loadingText = input('Procesando…', ...(ngDevMode ? [{ debugName: "loadingText" }] : /* istanbul ignore next */ []));
|
|
30
|
+
/** Visual style: 'danger', 'info' or 'warning'. */
|
|
31
|
+
this.type = input('danger', ...(ngDevMode ? [{ debugName: "type" }] : /* istanbul ignore next */ []));
|
|
32
|
+
/** Shows a spinner and disables the confirm button. */
|
|
33
|
+
this.loading = input(false, ...(ngDevMode ? [{ debugName: "loading" }] : /* istanbul ignore next */ []));
|
|
34
|
+
/** Whether the cancel button is shown. */
|
|
35
|
+
this.showCancel = input(true, ...(ngDevMode ? [{ debugName: "showCancel" }] : /* istanbul ignore next */ []));
|
|
36
|
+
/** Controls dialog visibility. */
|
|
37
|
+
this.visible = signal(false, ...(ngDevMode ? [{ debugName: "visible" }] : /* istanbul ignore next */ []));
|
|
38
|
+
/** Resolver of the currently pending confirmation promise. */
|
|
39
|
+
this.resolveRef = signal(null, ...(ngDevMode ? [{ debugName: "resolveRef" }] : /* istanbul ignore next */ []));
|
|
40
|
+
/** Emitted whenever the dialog is closed (confirm or cancel). */
|
|
41
|
+
this.closed = output();
|
|
42
|
+
}
|
|
43
|
+
/** Opens the dialog and returns a promise resolving with the user choice. */
|
|
44
|
+
show() {
|
|
45
|
+
this.visible.set(true);
|
|
46
|
+
return new Promise((resolve) => {
|
|
47
|
+
this.resolveRef.set(resolve);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/** Resolves with `true` when the user confirms. */
|
|
51
|
+
onConfirm() {
|
|
52
|
+
this.visible.set(false);
|
|
53
|
+
const resolve = this.resolveRef();
|
|
54
|
+
if (resolve) {
|
|
55
|
+
resolve(true);
|
|
56
|
+
this.resolveRef.set(null);
|
|
57
|
+
}
|
|
58
|
+
this.closed.emit();
|
|
59
|
+
}
|
|
60
|
+
/** Resolves with `false` when the user cancels. */
|
|
61
|
+
onCancel() {
|
|
62
|
+
this.visible.set(false);
|
|
63
|
+
const resolve = this.resolveRef();
|
|
64
|
+
if (resolve) {
|
|
65
|
+
resolve(false);
|
|
66
|
+
this.resolveRef.set(null);
|
|
67
|
+
}
|
|
68
|
+
this.closed.emit();
|
|
69
|
+
}
|
|
70
|
+
/** Clears the pending resolver on destroy. */
|
|
71
|
+
ngOnDestroy() {
|
|
72
|
+
this.resolveRef.set(null);
|
|
73
|
+
}
|
|
74
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
75
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.18", type: ConfirmDialogComponent, isStandalone: true, selector: "shk-confirm-dialog", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, confirmLabel: { classPropertyName: "confirmLabel", publicName: "confirmLabel", isSignal: true, isRequired: false, transformFunction: null }, cancelLabel: { classPropertyName: "cancelLabel", publicName: "cancelLabel", isSignal: true, isRequired: false, transformFunction: null }, loadingText: { classPropertyName: "loadingText", publicName: "loadingText", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, showCancel: { classPropertyName: "showCancel", publicName: "showCancel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, ngImport: i0, template: "@if (visible()) {\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-[9999] p-4\"\n (click)=\"onCancel()\"\n >\n <div\n class=\"bg-white dark:[background-color:var(--shk-surface-100)] rounded-2xl shadow-2xl max-w-sm w-full animate-in fade-in zoom-in duration-200 overflow-hidden\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"h-1.5 w-full\"\n [class.bg-gradient-to-r]=\"type() !== 'warning'\"\n [class.from-red-400]=\"type() === 'danger'\"\n [class.to-red-600]=\"type() === 'danger'\"\n [class.from-blue-400]=\"type() === 'info'\"\n [class.to-blue-600]=\"type() === 'info'\"\n [class.bg-amber-400]=\"type() === 'warning'\"\n ></div>\n <div class=\"p-6\">\n <div class=\"flex items-start gap-4 mb-4\">\n <div\n class=\"w-12 h-12 rounded-full flex items-center justify-center shrink-0\"\n [ngClass]=\"{\n 'bg-red-50 dark:bg-red-900/30 text-red-600 dark:text-red-400': type() === 'danger',\n 'bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400': type() === 'info',\n 'bg-amber-50 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400': type() === 'warning',\n }\"\n >\n @if (type() === 'info') {\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-6 h-6\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('triangle-alert')\" class=\"w-6 h-6\"></svg>\n }\n </div>\n <div>\n <h3 class=\"text-lg font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)]\">{{ title() }}</h3>\n <p class=\"_shk-text-surface-500 dark:[color:var(--shk-surface-400)] text-sm leading-relaxed mb-6\">{{ message() }}</p>\n </div>\n </div>\n <div class=\"flex gap-3\">\n @if (showCancel()) {\n <button\n type=\"button\"\n (click)=\"onCancel()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-600)] _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] hover:[background-color:var(--shk-surface-200)] dark:hover:[background-color:var(--shk-surface-300)] rounded-lg transition-colors flex items-center justify-center gap-2\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n {{ cancelLabel() }}\n </button>\n }\n <button\n type=\"button\"\n (click)=\"onConfirm()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold text-white rounded-lg shadow-md transition-all flex items-center justify-center gap-2\"\n [class.bg-red-600]=\"type() === 'danger'\"\n [class.hover:bg-red-700]=\"type() === 'danger'\"\n [class.shadow-red-500/20]=\"type() === 'danger'\"\n [class.bg-primary-600]=\"type() === 'info'\"\n [class.hover:bg-primary-700]=\"type() === 'info'\"\n [class.shadow-primary-500/20]=\"type() === 'info'\"\n [class.bg-amber-600]=\"type() === 'warning'\"\n [class.hover:bg-amber-700]=\"type() === 'warning'\"\n [class.shadow-amber-500/20]=\"type() === 'warning'\"\n >\n @if (loading()) {\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-4 h-4 animate-spin\"></svg>\n } @else if (type() === 'danger') {\n <svg [lucideIcon]=\"getIcon('trash-2')\" class=\"w-4 h-4\"></svg>\n }\n {{ loading() ? loadingText() : confirmLabel() }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "component", type: LucideDynamicIcon, selector: "svg[lucideIcon]", inputs: ["lucideIcon"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
76
|
+
}
|
|
77
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogComponent, decorators: [{
|
|
78
|
+
type: Component,
|
|
79
|
+
args: [{ selector: 'shk-confirm-dialog', standalone: true, imports: [CommonModule, LucideDynamicIcon], changeDetection: ChangeDetectionStrategy.OnPush, template: "@if (visible()) {\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-[9999] p-4\"\n (click)=\"onCancel()\"\n >\n <div\n class=\"bg-white dark:[background-color:var(--shk-surface-100)] rounded-2xl shadow-2xl max-w-sm w-full animate-in fade-in zoom-in duration-200 overflow-hidden\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"h-1.5 w-full\"\n [class.bg-gradient-to-r]=\"type() !== 'warning'\"\n [class.from-red-400]=\"type() === 'danger'\"\n [class.to-red-600]=\"type() === 'danger'\"\n [class.from-blue-400]=\"type() === 'info'\"\n [class.to-blue-600]=\"type() === 'info'\"\n [class.bg-amber-400]=\"type() === 'warning'\"\n ></div>\n <div class=\"p-6\">\n <div class=\"flex items-start gap-4 mb-4\">\n <div\n class=\"w-12 h-12 rounded-full flex items-center justify-center shrink-0\"\n [ngClass]=\"{\n 'bg-red-50 dark:bg-red-900/30 text-red-600 dark:text-red-400': type() === 'danger',\n 'bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400': type() === 'info',\n 'bg-amber-50 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400': type() === 'warning',\n }\"\n >\n @if (type() === 'info') {\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-6 h-6\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('triangle-alert')\" class=\"w-6 h-6\"></svg>\n }\n </div>\n <div>\n <h3 class=\"text-lg font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)]\">{{ title() }}</h3>\n <p class=\"_shk-text-surface-500 dark:[color:var(--shk-surface-400)] text-sm leading-relaxed mb-6\">{{ message() }}</p>\n </div>\n </div>\n <div class=\"flex gap-3\">\n @if (showCancel()) {\n <button\n type=\"button\"\n (click)=\"onCancel()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-600)] _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] hover:[background-color:var(--shk-surface-200)] dark:hover:[background-color:var(--shk-surface-300)] rounded-lg transition-colors flex items-center justify-center gap-2\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n {{ cancelLabel() }}\n </button>\n }\n <button\n type=\"button\"\n (click)=\"onConfirm()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold text-white rounded-lg shadow-md transition-all flex items-center justify-center gap-2\"\n [class.bg-red-600]=\"type() === 'danger'\"\n [class.hover:bg-red-700]=\"type() === 'danger'\"\n [class.shadow-red-500/20]=\"type() === 'danger'\"\n [class.bg-primary-600]=\"type() === 'info'\"\n [class.hover:bg-primary-700]=\"type() === 'info'\"\n [class.shadow-primary-500/20]=\"type() === 'info'\"\n [class.bg-amber-600]=\"type() === 'warning'\"\n [class.hover:bg-amber-700]=\"type() === 'warning'\"\n [class.shadow-amber-500/20]=\"type() === 'warning'\"\n >\n @if (loading()) {\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-4 h-4 animate-spin\"></svg>\n } @else if (type() === 'danger') {\n <svg [lucideIcon]=\"getIcon('trash-2')\" class=\"w-4 h-4\"></svg>\n }\n {{ loading() ? loadingText() : confirmLabel() }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n" }]
|
|
80
|
+
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], message: [{ type: i0.Input, args: [{ isSignal: true, alias: "message", required: false }] }], confirmLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirmLabel", required: false }] }], cancelLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "cancelLabel", required: false }] }], loadingText: [{ type: i0.Input, args: [{ isSignal: true, alias: "loadingText", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], showCancel: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCancel", required: false }] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Programmatically opens the confirmation dialog and resolves a Promise
|
|
84
|
+
* with the user's decision (true = confirm, false = cancel).
|
|
85
|
+
*/
|
|
86
|
+
class ConfirmDialogService {
|
|
87
|
+
constructor() {
|
|
88
|
+
/** Reference to the currently open dialog, if any. */
|
|
89
|
+
this.dialogRef = null;
|
|
90
|
+
this.destroyRef = inject(DestroyRef);
|
|
91
|
+
this.appRef = inject(ApplicationRef);
|
|
92
|
+
this.injector = inject(EnvironmentInjector);
|
|
93
|
+
this.destroyRef.onDestroy(() => this.cleanupDialog());
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Opens a confirmation dialog with the given configuration and returns a
|
|
97
|
+
* promise resolving with the user's choice.
|
|
98
|
+
*/
|
|
99
|
+
async confirm(config) {
|
|
100
|
+
if (this.dialogRef)
|
|
101
|
+
this.cleanupDialog();
|
|
102
|
+
this.dialogRef = createComponent(ConfirmDialogComponent, {
|
|
103
|
+
environmentInjector: this.injector,
|
|
104
|
+
});
|
|
105
|
+
this.dialogRef.setInput('title', config.title ?? 'Confirmar acción');
|
|
106
|
+
this.dialogRef.setInput('message', config.message);
|
|
107
|
+
this.dialogRef.setInput('confirmLabel', config.confirmLabel ?? 'Confirmar');
|
|
108
|
+
this.dialogRef.setInput('cancelLabel', config.cancelLabel ?? 'Cancelar');
|
|
109
|
+
this.dialogRef.setInput('loadingText', config.loadingText ?? 'Procesando…');
|
|
110
|
+
this.dialogRef.setInput('type', config.type ?? 'danger');
|
|
111
|
+
this.dialogRef.setInput('showCancel', config.showCancel ?? true);
|
|
112
|
+
this.dialogRef.setInput('loading', config.loading ?? false);
|
|
113
|
+
document.body.appendChild(this.dialogRef.location.nativeElement);
|
|
114
|
+
this.appRef.attachView(this.dialogRef.hostView);
|
|
115
|
+
try {
|
|
116
|
+
return await this.dialogRef.instance.show();
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
this.cleanupDialog();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/** Detaches and destroys the mounted dialog if present. */
|
|
123
|
+
cleanupDialog() {
|
|
124
|
+
if (this.dialogRef) {
|
|
125
|
+
this.appRef.detachView(this.dialogRef.hostView);
|
|
126
|
+
this.dialogRef.destroy();
|
|
127
|
+
this.dialogRef = null;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
131
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, providedIn: 'root' }); }
|
|
132
|
+
}
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.18", ngImport: i0, type: ConfirmDialogService, decorators: [{
|
|
134
|
+
type: Injectable,
|
|
135
|
+
args: [{ providedIn: 'root' }]
|
|
136
|
+
}], ctorParameters: () => [] });
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Generated bundle index. Do not edit.
|
|
140
|
+
*/
|
|
141
|
+
|
|
142
|
+
export { ConfirmDialogComponent, ConfirmDialogService };
|
|
143
|
+
//# sourceMappingURL=shirkasoft-ui-components-confirm-dialog.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shirkasoft-ui-components-confirm-dialog.mjs","sources":["../../../projects/ui-components/confirm-dialog/confirm-dialog.component.ts","../../../projects/ui-components/confirm-dialog/confirm-dialog.component.html","../../../projects/ui-components/confirm-dialog/confirm-dialog.service.ts","../../../projects/ui-components/confirm-dialog/shirkasoft-ui-components-confirm-dialog.ts"],"sourcesContent":["import { Component, ChangeDetectionStrategy, input, output, signal, OnDestroy } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { LucideDynamicIcon, LucideTriangleAlert } from '@lucide/angular';\nimport { getIcon as getIconFromCentral } from 'shirkasoft-ui-components/utils';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/**\n * Confirmation dialog opened via `show()` which resolves a Promise<boolean>\n * with the user's choice.\n */\n@Component({\n selector: 'shk-confirm-dialog',\n standalone: true,\n imports: [CommonModule, LucideDynamicIcon],\n templateUrl: './confirm-dialog.component.html',\n changeDetection: ChangeDetectionStrategy.OnPush,\n})\nexport class ConfirmDialogComponent implements OnDestroy {\n protected getIcon = (name: any) => getIconFromCentral(name, LucideTriangleAlert);\n\n /** Title shown in the dialog header. */\n title = input<string>('Confirmar acción');\n /** Message body of the dialog. */\n message = input<string>('¿Está seguro de realizar esta acción?');\n /** Label of the confirm button. */\n confirmLabel = input<string>('Confirmar');\n /** Label of the cancel button. */\n cancelLabel = input<string>('Cancelar');\n /** Text shown on the confirm button while `loading` is true. */\n loadingText = input<string>('Procesando…');\n /** Visual style: 'danger', 'info' or 'warning'. */\n type = input<'danger' | 'info' | 'warning'>('danger');\n /** Shows a spinner and disables the confirm button. */\n loading = input<boolean>(false);\n /** Whether the cancel button is shown. */\n showCancel = input<boolean>(true);\n\n /** Controls dialog visibility. */\n visible = signal<boolean>(false);\n /** Resolver of the currently pending confirmation promise. */\n private resolveRef = signal<((value: boolean) => void) | null>(null);\n\n /** Emitted whenever the dialog is closed (confirm or cancel). */\n closed = output<void>();\n\n /** Opens the dialog and returns a promise resolving with the user choice. */\n show(): Promise<boolean> {\n this.visible.set(true);\n return new Promise((resolve) => {\n this.resolveRef.set(resolve);\n });\n }\n\n /** Resolves with `true` when the user confirms. */\n onConfirm() {\n this.visible.set(false);\n const resolve = this.resolveRef();\n if (resolve) {\n resolve(true);\n this.resolveRef.set(null);\n }\n this.closed.emit();\n }\n\n /** Resolves with `false` when the user cancels. */\n onCancel() {\n this.visible.set(false);\n const resolve = this.resolveRef();\n if (resolve) {\n resolve(false);\n this.resolveRef.set(null);\n }\n this.closed.emit();\n }\n\n /** Clears the pending resolver on destroy. */\n ngOnDestroy() {\n this.resolveRef.set(null);\n }\n}\n","@if (visible()) {\n <div\n class=\"fixed inset-0 bg-black/40 backdrop-blur-sm flex items-center justify-center z-[9999] p-4\"\n (click)=\"onCancel()\"\n >\n <div\n class=\"bg-white dark:[background-color:var(--shk-surface-100)] rounded-2xl shadow-2xl max-w-sm w-full animate-in fade-in zoom-in duration-200 overflow-hidden\"\n (click)=\"$event.stopPropagation()\"\n >\n <div\n class=\"h-1.5 w-full\"\n [class.bg-gradient-to-r]=\"type() !== 'warning'\"\n [class.from-red-400]=\"type() === 'danger'\"\n [class.to-red-600]=\"type() === 'danger'\"\n [class.from-blue-400]=\"type() === 'info'\"\n [class.to-blue-600]=\"type() === 'info'\"\n [class.bg-amber-400]=\"type() === 'warning'\"\n ></div>\n <div class=\"p-6\">\n <div class=\"flex items-start gap-4 mb-4\">\n <div\n class=\"w-12 h-12 rounded-full flex items-center justify-center shrink-0\"\n [ngClass]=\"{\n 'bg-red-50 dark:bg-red-900/30 text-red-600 dark:text-red-400': type() === 'danger',\n 'bg-blue-50 dark:bg-blue-900/30 text-blue-600 dark:text-blue-400': type() === 'info',\n 'bg-amber-50 dark:bg-amber-900/30 text-amber-600 dark:text-amber-400': type() === 'warning',\n }\"\n >\n @if (type() === 'info') {\n <svg [lucideIcon]=\"getIcon('info')\" class=\"w-6 h-6\"></svg>\n } @else {\n <svg [lucideIcon]=\"getIcon('triangle-alert')\" class=\"w-6 h-6\"></svg>\n }\n </div>\n <div>\n <h3 class=\"text-lg font-bold _shk-text-surface-800 dark:[color:var(--shk-surface-800)]\">{{ title() }}</h3>\n <p class=\"_shk-text-surface-500 dark:[color:var(--shk-surface-400)] text-sm leading-relaxed mb-6\">{{ message() }}</p>\n </div>\n </div>\n <div class=\"flex gap-3\">\n @if (showCancel()) {\n <button\n type=\"button\"\n (click)=\"onCancel()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold _shk-text-surface-600 dark:[color:var(--shk-surface-600)] _shk-bg-surface-100 dark:[background-color:var(--shk-surface-200)] hover:[background-color:var(--shk-surface-200)] dark:hover:[background-color:var(--shk-surface-300)] rounded-lg transition-colors flex items-center justify-center gap-2\"\n >\n <svg [lucideIcon]=\"getIcon('x')\" class=\"w-4 h-4\"></svg>\n {{ cancelLabel() }}\n </button>\n }\n <button\n type=\"button\"\n (click)=\"onConfirm()\"\n [disabled]=\"loading()\"\n class=\"flex-1 px-4 py-2 text-sm font-semibold text-white rounded-lg shadow-md transition-all flex items-center justify-center gap-2\"\n [class.bg-red-600]=\"type() === 'danger'\"\n [class.hover:bg-red-700]=\"type() === 'danger'\"\n [class.shadow-red-500/20]=\"type() === 'danger'\"\n [class.bg-primary-600]=\"type() === 'info'\"\n [class.hover:bg-primary-700]=\"type() === 'info'\"\n [class.shadow-primary-500/20]=\"type() === 'info'\"\n [class.bg-amber-600]=\"type() === 'warning'\"\n [class.hover:bg-amber-700]=\"type() === 'warning'\"\n [class.shadow-amber-500/20]=\"type() === 'warning'\"\n >\n @if (loading()) {\n <svg [lucideIcon]=\"getIcon('loader')\" class=\"w-4 h-4 animate-spin\"></svg>\n } @else if (type() === 'danger') {\n <svg [lucideIcon]=\"getIcon('trash-2')\" class=\"w-4 h-4\"></svg>\n }\n {{ loading() ? loadingText() : confirmLabel() }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n","import {\n Injectable,\n ComponentRef,\n ApplicationRef,\n createComponent,\n EnvironmentInjector,\n DestroyRef,\n inject,\n} from '@angular/core';\nimport { ConfirmDialogComponent } from './confirm-dialog.component';\n\n/**\n * Shirkasoft UI Components.\n * Authors: Roberto Valladares Martin (Ansem13), Julio César García García (Sanjuli14).\n * Belongs to Shirkasoft.\n */\n\n/** Options for opening a confirmation dialog. */\nexport interface ConfirmConfig {\n title?: string;\n message: string;\n confirmLabel?: string;\n cancelLabel?: string;\n loadingText?: string;\n type?: 'danger' | 'info' | 'warning';\n showCancel?: boolean;\n loading?: boolean;\n}\n\n/**\n * Programmatically opens the confirmation dialog and resolves a Promise\n * with the user's decision (true = confirm, false = cancel).\n */\n@Injectable({ providedIn: 'root' })\nexport class ConfirmDialogService {\n /** Reference to the currently open dialog, if any. */\n private dialogRef: ComponentRef<ConfirmDialogComponent> | null = null;\n\n private destroyRef = inject(DestroyRef);\n private appRef = inject(ApplicationRef);\n private injector = inject(EnvironmentInjector);\n\n constructor() {\n this.destroyRef.onDestroy(() => this.cleanupDialog());\n }\n\n /**\n * Opens a confirmation dialog with the given configuration and returns a\n * promise resolving with the user's choice.\n */\n async confirm(config: ConfirmConfig): Promise<boolean> {\n if (this.dialogRef) this.cleanupDialog();\n\n this.dialogRef = createComponent(ConfirmDialogComponent, {\n environmentInjector: this.injector,\n });\n\n this.dialogRef.setInput('title', config.title ?? 'Confirmar acción');\n this.dialogRef.setInput('message', config.message);\n this.dialogRef.setInput('confirmLabel', config.confirmLabel ?? 'Confirmar');\n this.dialogRef.setInput('cancelLabel', config.cancelLabel ?? 'Cancelar');\n this.dialogRef.setInput('loadingText', config.loadingText ?? 'Procesando…');\n this.dialogRef.setInput('type', config.type ?? 'danger');\n this.dialogRef.setInput('showCancel', config.showCancel ?? true);\n this.dialogRef.setInput('loading', config.loading ?? false);\n\n document.body.appendChild(this.dialogRef.location.nativeElement);\n this.appRef.attachView(this.dialogRef.hostView);\n try {\n return await this.dialogRef.instance.show();\n } finally {\n this.cleanupDialog();\n }\n }\n\n /** Detaches and destroys the mounted dialog if present. */\n private cleanupDialog(): void {\n if (this.dialogRef) {\n this.appRef.detachView(this.dialogRef.hostView);\n this.dialogRef.destroy();\n this.dialogRef = null;\n }\n }\n}","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["getIconFromCentral"],"mappings":"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"}
|