pdm-ui-kit 0.1.50 → 0.2.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/README.md +189 -2
- package/esm2020/lib/components/alert-dialog/alert-dialog.component.mjs +3 -3
- package/esm2020/lib/components/breadcrumb/breadcrumb.component.mjs +37 -4
- package/esm2020/lib/components/calendar/calendar.component.mjs +3 -3
- package/esm2020/lib/components/card/card.component.mjs +36 -53
- package/esm2020/lib/components/command/command.component.mjs +3 -3
- package/esm2020/lib/components/context-menu/context-menu.component.mjs +3 -3
- package/esm2020/lib/components/data-table/data-table.component.mjs +214 -16
- package/esm2020/lib/components/dialog/dialog.component.mjs +133 -17
- package/esm2020/lib/components/draggable-table/draggable-table.component.mjs +300 -0
- package/esm2020/lib/components/drawer/drawer.component.mjs +123 -16
- package/esm2020/lib/components/dropdown-menu/dropdown-menu.component.mjs +3 -2
- package/esm2020/lib/components/hover-card/hover-card.component.mjs +3 -3
- package/esm2020/lib/components/menubar/menubar.component.mjs +3 -3
- package/esm2020/lib/components/navigation-menu/navigation-menu.component.mjs +25 -3
- package/esm2020/lib/components/pagination/pagination.component.mjs +3 -3
- package/esm2020/lib/components/popover/popover.component.mjs +5 -3
- package/esm2020/lib/components/select/select.component.mjs +5 -3
- package/esm2020/lib/components/sheet/sheet.component.mjs +68 -12
- package/esm2020/lib/components/sidebar/sidebar.component.mjs +52 -5
- package/esm2020/lib/components/table/table.component.mjs +152 -188
- package/esm2020/lib/components/tabs/tabs.component.mjs +3 -3
- package/esm2020/lib/components/tooltip/tooltip.component.mjs +3 -3
- package/esm2020/lib/pdm-ui-kit.module.mjs +5 -1
- package/esm2020/lib/utils/responsive.mjs +143 -0
- package/esm2020/lib/utils/z-index.mjs +93 -0
- package/esm2020/public-api.mjs +4 -1
- package/fesm2015/pdm-ui-kit.mjs +1430 -371
- package/fesm2015/pdm-ui-kit.mjs.map +1 -1
- package/fesm2020/pdm-ui-kit.mjs +1428 -369
- package/fesm2020/pdm-ui-kit.mjs.map +1 -1
- package/lib/components/breadcrumb/breadcrumb.component.d.ts +23 -1
- package/lib/components/card/card.component.d.ts +32 -19
- package/lib/components/data-table/data-table.component.d.ts +172 -14
- package/lib/components/dialog/dialog.component.d.ts +35 -1
- package/lib/components/draggable-table/draggable-table.component.d.ts +74 -0
- package/lib/components/drawer/drawer.component.d.ts +65 -7
- package/lib/components/navigation-menu/navigation-menu.component.d.ts +22 -1
- package/lib/components/sheet/sheet.component.d.ts +30 -3
- package/lib/components/sidebar/sidebar.component.d.ts +39 -1
- package/lib/components/table/table.component.d.ts +46 -25
- package/lib/pdm-ui-kit.module.d.ts +42 -41
- package/lib/utils/responsive.d.ts +107 -0
- package/lib/utils/z-index.d.ts +73 -0
- package/package.json +5 -3
- package/public-api.d.ts +3 -0
package/fesm2020/pdm-ui-kit.mjs
CHANGED
|
@@ -131,10 +131,10 @@ class PdmAlertDialogComponent {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
PdmAlertDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
134
|
-
PdmAlertDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmAlertDialogComponent, selector: "pdm-alert-dialog", inputs: { open: "open", showTrigger: "showTrigger", triggerText: "triggerText", title: "title", description: "description", confirmText: "confirmText", cancelText: "cancelText", className: "className", closeOnEsc: "closeOnEsc" }, outputs: { openChange: "openChange", confirm: "confirm", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-
|
|
134
|
+
PdmAlertDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmAlertDialogComponent, selector: "pdm-alert-dialog", inputs: { open: "open", showTrigger: "showTrigger", triggerText: "triggerText", title: "title", description: "description", confirmText: "confirmText", cancelText: "cancelText", className: "className", closeOnEsc: "closeOnEsc" }, outputs: { openChange: "openChange", confirm: "confirm", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-[60] w-full max-w-lg rounded-lg border border-border bg-background p-6 text-foreground shadow-lg',\n className\n ]\"\n >\n <div class=\"flex flex-col gap-2\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <div class=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onCancel()\"\n >\n {{ cancelText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm\"\n (click)=\"onConfirm()\"\n >\n {{ confirmText }}\n </button>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
135
135
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, decorators: [{
|
|
136
136
|
type: Component,
|
|
137
|
-
args: [{ selector: 'pdm-alert-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-
|
|
137
|
+
args: [{ selector: 'pdm-alert-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-[60] w-full max-w-lg rounded-lg border border-border bg-background p-6 text-foreground shadow-lg',\n className\n ]\"\n >\n <div class=\"flex flex-col gap-2\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <div class=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onCancel()\"\n >\n {{ cancelText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm\"\n (click)=\"onConfirm()\"\n >\n {{ confirmText }}\n </button>\n </div>\n </section>\n</div>\n" }]
|
|
138
138
|
}], propDecorators: { open: [{
|
|
139
139
|
type: Input
|
|
140
140
|
}], showTrigger: [{
|
|
@@ -255,30 +255,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
255
255
|
type: Input
|
|
256
256
|
}] } });
|
|
257
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Breadcrumb component con soporte responsive
|
|
260
|
+
*
|
|
261
|
+
* MEJORADO en v0.2.0:
|
|
262
|
+
* - Modo responsive real con overflow-x-auto
|
|
263
|
+
* - Collapse inteligente en mobile
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* <pdm-breadcrumb
|
|
267
|
+
* mode="responsive"
|
|
268
|
+
* [items]="['Home', 'Products', 'Electronics', 'Laptops']">
|
|
269
|
+
* </pdm-breadcrumb>
|
|
270
|
+
*/
|
|
258
271
|
class PdmBreadcrumbComponent {
|
|
259
272
|
constructor() {
|
|
260
273
|
this.mode = 'link-component';
|
|
261
274
|
this.items = ['Home', 'Components', 'Breadcrumb'];
|
|
262
275
|
this.className = '';
|
|
276
|
+
/**
|
|
277
|
+
* Cantidad mínima de items para mostrar en mobile cuando mode="responsive"
|
|
278
|
+
* Default: 2 (primer y último item)
|
|
279
|
+
*/
|
|
280
|
+
this.minItemsMobile = 2;
|
|
263
281
|
}
|
|
264
282
|
get renderedItems() {
|
|
265
|
-
if (
|
|
283
|
+
if (this.mode === 'collapsed' && this.items.length > 3) {
|
|
266
284
|
return [this.items[0], '...', this.items[this.items.length - 2], this.items[this.items.length - 1]];
|
|
267
285
|
}
|
|
286
|
+
// Responsive mode: no collapse en el TS, se maneja en el template con CSS
|
|
268
287
|
return this.items;
|
|
269
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Determina si un item debe estar visible en mobile (modo responsive)
|
|
291
|
+
*/
|
|
292
|
+
shouldShowInMobile(index) {
|
|
293
|
+
if (this.mode !== 'responsive')
|
|
294
|
+
return true;
|
|
295
|
+
const totalItems = this.items.length;
|
|
296
|
+
if (totalItems <= this.minItemsMobile)
|
|
297
|
+
return true;
|
|
298
|
+
// Siempre mostrar primero y último
|
|
299
|
+
return index === 0 || index === totalItems - 1;
|
|
300
|
+
}
|
|
270
301
|
}
|
|
271
302
|
PdmBreadcrumbComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
272
|
-
PdmBreadcrumbComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmBreadcrumbComponent, selector: "pdm-breadcrumb", inputs: { mode: "mode", items: "items", className: "className" }, ngImport: i0, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
303
|
+
PdmBreadcrumbComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmBreadcrumbComponent, selector: "pdm-breadcrumb", inputs: { mode: "mode", items: "items", className: "className", minItemsMobile: "minItemsMobile" }, ngImport: i0, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"[\n 'inline-flex items-center gap-1.5 text-sm',\n mode === 'responsive' ? 'overflow-x-auto max-w-full pb-1 scrollbar-thin' : '',\n className\n ]\"\n>\n <ng-container *ngFor=\"let item of renderedItems; let i = index; let last = last\">\n <!-- Item text -->\n <span \n [ngClass]=\"[\n last ? 'text-foreground font-medium' : 'text-muted-foreground hover:text-foreground transition-colors cursor-pointer',\n mode === 'responsive' && !shouldShowInMobile(i) ? 'hidden sm:inline' : '',\n 'whitespace-nowrap'\n ]\">\n {{ item }}\n </span>\n\n <!-- Separator -->\n <ng-container *ngIf=\"!last\">\n <span \n [ngClass]=\"[\n 'inline-flex h-6 w-6 flex-shrink-0 items-center justify-center text-muted-foreground',\n mode === 'responsive' && !shouldShowInMobile(i) && !shouldShowInMobile(i + 1) ? 'hidden sm:inline-flex' : ''\n ]\" \n aria-hidden=\"true\">\n <!-- Custom separator (slash) -->\n <svg\n *ngIf=\"mode === 'custom-separator' && item !== '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M8 20L16 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n \n <!-- Default separator (chevron) -->\n <svg\n *ngIf=\"(mode !== 'custom-separator' && item !== '...') || item === '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n \n <!-- Ellipsis indicator for responsive mode (only shown when items are hidden) -->\n <span \n *ngIf=\"mode === 'responsive' && !shouldShowInMobile(i) && i === 0\"\n class=\"inline-flex sm:hidden text-muted-foreground\">\n ...\n </span>\n </ng-container>\n\n <!-- Dropdown indicator -->\n <ng-container *ngIf=\"mode === 'dropdown' && i === 1 && item !== '...' && !last\">\n <span class=\"-ml-2 inline-flex h-6 w-6 items-center justify-center text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </ng-container>\n </ng-container>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
273
304
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, decorators: [{
|
|
274
305
|
type: Component,
|
|
275
|
-
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
306
|
+
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"[\n 'inline-flex items-center gap-1.5 text-sm',\n mode === 'responsive' ? 'overflow-x-auto max-w-full pb-1 scrollbar-thin' : '',\n className\n ]\"\n>\n <ng-container *ngFor=\"let item of renderedItems; let i = index; let last = last\">\n <!-- Item text -->\n <span \n [ngClass]=\"[\n last ? 'text-foreground font-medium' : 'text-muted-foreground hover:text-foreground transition-colors cursor-pointer',\n mode === 'responsive' && !shouldShowInMobile(i) ? 'hidden sm:inline' : '',\n 'whitespace-nowrap'\n ]\">\n {{ item }}\n </span>\n\n <!-- Separator -->\n <ng-container *ngIf=\"!last\">\n <span \n [ngClass]=\"[\n 'inline-flex h-6 w-6 flex-shrink-0 items-center justify-center text-muted-foreground',\n mode === 'responsive' && !shouldShowInMobile(i) && !shouldShowInMobile(i + 1) ? 'hidden sm:inline-flex' : ''\n ]\" \n aria-hidden=\"true\">\n <!-- Custom separator (slash) -->\n <svg\n *ngIf=\"mode === 'custom-separator' && item !== '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M8 20L16 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n \n <!-- Default separator (chevron) -->\n <svg\n *ngIf=\"(mode !== 'custom-separator' && item !== '...') || item === '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n \n <!-- Ellipsis indicator for responsive mode (only shown when items are hidden) -->\n <span \n *ngIf=\"mode === 'responsive' && !shouldShowInMobile(i) && i === 0\"\n class=\"inline-flex sm:hidden text-muted-foreground\">\n ...\n </span>\n </ng-container>\n\n <!-- Dropdown indicator -->\n <ng-container *ngIf=\"mode === 'dropdown' && i === 1 && item !== '...' && !last\">\n <span class=\"-ml-2 inline-flex h-6 w-6 items-center justify-center text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </ng-container>\n </ng-container>\n</nav>\n" }]
|
|
276
307
|
}], propDecorators: { mode: [{
|
|
277
308
|
type: Input
|
|
278
309
|
}], items: [{
|
|
279
310
|
type: Input
|
|
280
311
|
}], className: [{
|
|
281
312
|
type: Input
|
|
313
|
+
}], minItemsMobile: [{
|
|
314
|
+
type: Input
|
|
282
315
|
}] } });
|
|
283
316
|
|
|
284
317
|
class PdmButtonGroupComponent {
|
|
@@ -1058,10 +1091,10 @@ class PdmCalendarComponent {
|
|
|
1058
1091
|
}
|
|
1059
1092
|
}
|
|
1060
1093
|
PdmCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1061
|
-
PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { variant: "variant", className: "className", disabledDates: "disabledDates", minDate: "minDate", maxDate: "maxDate", minYear: "minYear", maxYear: "maxYear", isDateDisabled: "isDateDisabled", allowSameDayRange: "allowSameDayRange", readonly: "readonly", value: "value", rangeValue: "rangeValue", month: "month" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", monthChange: "monthChange", dateClick: "dateClick", disabledDateClick: "disabledDateClick" }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1094
|
+
PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { variant: "variant", className: "className", disabledDates: "disabledDates", minDate: "minDate", maxDate: "maxDate", minYear: "minYear", maxYear: "maxYear", isDateDisabled: "isDateDisabled", allowSameDayRange: "allowSameDayRange", readonly: "readonly", value: "value", rangeValue: "rangeValue", month: "month" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", monthChange: "monthChange", dateClick: "dateClick", disabledDateClick: "disabledDateClick" }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1062
1095
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, decorators: [{
|
|
1063
1096
|
type: Component,
|
|
1064
|
-
args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
1097
|
+
args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
1065
1098
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { variant: [{
|
|
1066
1099
|
type: Input
|
|
1067
1100
|
}], className: [{
|
|
@@ -1199,66 +1232,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1199
1232
|
type: Output
|
|
1200
1233
|
}] } });
|
|
1201
1234
|
|
|
1235
|
+
/**
|
|
1236
|
+
* Card component - Visual container primitivo
|
|
1237
|
+
*
|
|
1238
|
+
* BREAKING CHANGE en v0.2.0: variant="login" eliminado.
|
|
1239
|
+
* Card es ahora un componente UI puro sin lógica de negocio.
|
|
1240
|
+
*
|
|
1241
|
+
* Para crear un login form, componer con primitivos:
|
|
1242
|
+
*
|
|
1243
|
+
* @example
|
|
1244
|
+
* <pdm-card>
|
|
1245
|
+
* <div pdmCardHeader>
|
|
1246
|
+
* <h3 class="text-lg font-semibold">Login</h3>
|
|
1247
|
+
* <p class="text-sm text-muted-foreground">Enter your credentials</p>
|
|
1248
|
+
* </div>
|
|
1249
|
+
* <div pdmCardContent>
|
|
1250
|
+
* <form [formGroup]="form">
|
|
1251
|
+
* <pdm-field>
|
|
1252
|
+
* <pdm-label>Email</pdm-label>
|
|
1253
|
+
* <pdm-input type="email" formControlName="email" />
|
|
1254
|
+
* </pdm-field>
|
|
1255
|
+
* <pdm-field>
|
|
1256
|
+
* <pdm-label>Password</pdm-label>
|
|
1257
|
+
* <pdm-input-password formControlName="password" />
|
|
1258
|
+
* </pdm-field>
|
|
1259
|
+
* </form>
|
|
1260
|
+
* </div>
|
|
1261
|
+
* <div pdmCardFooter>
|
|
1262
|
+
* <pdm-button (click)="onLogin()">Login</pdm-button>
|
|
1263
|
+
* </div>
|
|
1264
|
+
* </pdm-card>
|
|
1265
|
+
*/
|
|
1202
1266
|
class PdmCardComponent {
|
|
1203
1267
|
constructor() {
|
|
1204
|
-
this.variant = 'default';
|
|
1205
1268
|
this.className = '';
|
|
1206
|
-
this.title = 'Login to your account';
|
|
1207
|
-
this.description = 'Enter your email below to login to your account';
|
|
1208
|
-
this.actionText = 'Sign up';
|
|
1209
|
-
this.emailLabel = 'Email';
|
|
1210
|
-
this.emailPlaceholder = 'm@example.com';
|
|
1211
|
-
this.passwordLabel = 'Password';
|
|
1212
|
-
this.passwordHint = 'Forgot password?';
|
|
1213
|
-
this.primaryActionText = 'Login';
|
|
1214
|
-
this.secondaryActionText = 'Login with Google';
|
|
1215
|
-
this.primaryAction = new EventEmitter();
|
|
1216
|
-
this.secondaryAction = new EventEmitter();
|
|
1217
|
-
this.actionPressed = new EventEmitter();
|
|
1218
|
-
}
|
|
1219
|
-
onPrimaryAction() {
|
|
1220
|
-
this.primaryAction.emit();
|
|
1221
|
-
}
|
|
1222
|
-
onSecondaryAction() {
|
|
1223
|
-
this.secondaryAction.emit();
|
|
1224
|
-
}
|
|
1225
|
-
onActionPressed() {
|
|
1226
|
-
this.actionPressed.emit();
|
|
1227
1269
|
}
|
|
1228
1270
|
}
|
|
1229
1271
|
PdmCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1230
|
-
PdmCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCardComponent, selector: "pdm-card", inputs: {
|
|
1272
|
+
PdmCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCardComponent, selector: "pdm-card", inputs: { className: "className" }, ngImport: i0, template: "<section\n [ngClass]=\"[\n 'w-full rounded-lg border border-border bg-background py-6 shadow-sm',\n className\n ]\"\n>\n <div class=\"flex w-full flex-col gap-6\">\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardHeader]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardContent]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardFooter]\"></ng-content>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1231
1273
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, decorators: [{
|
|
1232
1274
|
type: Component,
|
|
1233
|
-
args: [{ selector: 'pdm-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n [ngClass]=\"[\n 'w-full rounded-lg border border-border bg-background py-6 shadow-sm',\n className\n ]\"\n>\n <
|
|
1234
|
-
}], propDecorators: {
|
|
1235
|
-
type: Input
|
|
1236
|
-
}], className: [{
|
|
1237
|
-
type: Input
|
|
1238
|
-
}], title: [{
|
|
1239
|
-
type: Input
|
|
1240
|
-
}], description: [{
|
|
1241
|
-
type: Input
|
|
1242
|
-
}], actionText: [{
|
|
1243
|
-
type: Input
|
|
1244
|
-
}], emailLabel: [{
|
|
1245
|
-
type: Input
|
|
1246
|
-
}], emailPlaceholder: [{
|
|
1247
|
-
type: Input
|
|
1248
|
-
}], passwordLabel: [{
|
|
1249
|
-
type: Input
|
|
1250
|
-
}], passwordHint: [{
|
|
1251
|
-
type: Input
|
|
1252
|
-
}], primaryActionText: [{
|
|
1253
|
-
type: Input
|
|
1254
|
-
}], secondaryActionText: [{
|
|
1275
|
+
args: [{ selector: 'pdm-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n [ngClass]=\"[\n 'w-full rounded-lg border border-border bg-background py-6 shadow-sm',\n className\n ]\"\n>\n <div class=\"flex w-full flex-col gap-6\">\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardHeader]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardContent]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardFooter]\"></ng-content>\n </div>\n </div>\n</section>\n" }]
|
|
1276
|
+
}], propDecorators: { className: [{
|
|
1255
1277
|
type: Input
|
|
1256
|
-
}], primaryAction: [{
|
|
1257
|
-
type: Output
|
|
1258
|
-
}], secondaryAction: [{
|
|
1259
|
-
type: Output
|
|
1260
|
-
}], actionPressed: [{
|
|
1261
|
-
type: Output
|
|
1262
1278
|
}] } });
|
|
1263
1279
|
|
|
1264
1280
|
class PdmChartComponent {
|
|
@@ -1753,10 +1769,10 @@ class PdmCommandComponent {
|
|
|
1753
1769
|
}
|
|
1754
1770
|
}
|
|
1755
1771
|
PdmCommandComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1756
|
-
PdmCommandComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCommandComponent, selector: "pdm-command", inputs: { open: "open", hintLabel: "hintLabel", hintKey: "hintKey", placeholder: "placeholder", emptyMessage: "emptyMessage", items: "items", className: "className" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-
|
|
1772
|
+
PdmCommandComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCommandComponent, selector: "pdm-command", inputs: { open: "open", hintLabel: "hintLabel", hintKey: "hintKey", placeholder: "placeholder", emptyMessage: "emptyMessage", items: "items", className: "className" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-[50vh] overflow-y-auto p-1 md:max-h-72\">\n <ng-container *ngFor=\"let group of groupedItems; let groupIndex = index\">\n <div *ngIf=\"group.name\" class=\"px-2 py-1.5 text-xs text-muted-foreground\">{{ group.name }}</div>\n <button\n *ngFor=\"let item of group.items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"[\n item.disabled ? 'opacity-50' : '',\n item.label === 'Calendar' ? 'bg-accent text-accent-foreground' : ''\n ]\"\n (click)=\"select(item.value)\"\n >\n <span class=\"inline-flex h-4 w-4 items-center justify-center text-foreground\">\n <pdm-icon *ngIf=\"item.icon\" [name]=\"item.icon\" [size]=\"16\" [decorative]=\"true\"></pdm-icon>\n </span>\n <span class=\"min-w-0 flex-1 text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n </button>\n <div *ngIf=\"groupIndex === 0 && groupedItems.length > 1\" class=\"my-1 border-t border-border\"></div>\n </ng-container>\n\n <p *ngIf=\"filteredItems.length === 0\" class=\"m-0 py-6 text-center text-sm text-muted-foreground\">{{ emptyMessage }}</p>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1757
1773
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, decorators: [{
|
|
1758
1774
|
type: Component,
|
|
1759
|
-
args: [{ selector: 'pdm-command', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-
|
|
1775
|
+
args: [{ selector: 'pdm-command', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-[50vh] overflow-y-auto p-1 md:max-h-72\">\n <ng-container *ngFor=\"let group of groupedItems; let groupIndex = index\">\n <div *ngIf=\"group.name\" class=\"px-2 py-1.5 text-xs text-muted-foreground\">{{ group.name }}</div>\n <button\n *ngFor=\"let item of group.items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"[\n item.disabled ? 'opacity-50' : '',\n item.label === 'Calendar' ? 'bg-accent text-accent-foreground' : ''\n ]\"\n (click)=\"select(item.value)\"\n >\n <span class=\"inline-flex h-4 w-4 items-center justify-center text-foreground\">\n <pdm-icon *ngIf=\"item.icon\" [name]=\"item.icon\" [size]=\"16\" [decorative]=\"true\"></pdm-icon>\n </span>\n <span class=\"min-w-0 flex-1 text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n </button>\n <div *ngIf=\"groupIndex === 0 && groupedItems.length > 1\" class=\"my-1 border-t border-border\"></div>\n </ng-container>\n\n <p *ngIf=\"filteredItems.length === 0\" class=\"m-0 py-6 text-center text-sm text-muted-foreground\">{{ emptyMessage }}</p>\n </div>\n </section>\n</div>\n" }]
|
|
1760
1776
|
}], propDecorators: { open: [{
|
|
1761
1777
|
type: Input
|
|
1762
1778
|
}], hintLabel: [{
|
|
@@ -1839,10 +1855,10 @@ class PdmContextMenuComponent {
|
|
|
1839
1855
|
}
|
|
1840
1856
|
}
|
|
1841
1857
|
PdmContextMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1842
|
-
PdmContextMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmContextMenuComponent, selector: "pdm-context-menu", inputs: { items: "items", className: "className", triggerLabel: "triggerLabel", width: "width", height: "height" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-
|
|
1858
|
+
PdmContextMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmContextMenuComponent, selector: "pdm-context-menu", inputs: { items: "items", className: "className", triggerLabel: "triggerLabel", width: "width", height: "height" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1843
1859
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, decorators: [{
|
|
1844
1860
|
type: Component,
|
|
1845
|
-
args: [{ selector: 'pdm-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-
|
|
1861
|
+
args: [{ selector: 'pdm-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n</div>\n" }]
|
|
1846
1862
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { items: [{
|
|
1847
1863
|
type: Input
|
|
1848
1864
|
}], className: [{
|
|
@@ -1860,31 +1876,459 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1860
1876
|
args: ['document:keydown.escape']
|
|
1861
1877
|
}] } });
|
|
1862
1878
|
|
|
1879
|
+
/**
|
|
1880
|
+
* Sistema de responsive utilities para PDM UI Kit
|
|
1881
|
+
*
|
|
1882
|
+
* Proporciona constantes, tipos y helpers para manejar responsive design
|
|
1883
|
+
* de forma consistente en todos los componentes.
|
|
1884
|
+
*/
|
|
1885
|
+
/**
|
|
1886
|
+
* Breakpoints estándar de Tailwind CSS
|
|
1887
|
+
* Mobile-first approach: los estilos base son para mobile, los breakpoints son MIN-WIDTH
|
|
1888
|
+
*/
|
|
1889
|
+
const BREAKPOINTS = {
|
|
1890
|
+
sm: '640px',
|
|
1891
|
+
md: '768px',
|
|
1892
|
+
lg: '1024px',
|
|
1893
|
+
xl: '1280px',
|
|
1894
|
+
'2xl': '1536px' // extra large desktop
|
|
1895
|
+
};
|
|
1896
|
+
/**
|
|
1897
|
+
* Helper para generar clases responsive de forma programática
|
|
1898
|
+
*
|
|
1899
|
+
* @example
|
|
1900
|
+
* responsive({ default: 'block', sm: 'flex', lg: 'grid' })
|
|
1901
|
+
* // Returns: 'block sm:flex lg:grid'
|
|
1902
|
+
*/
|
|
1903
|
+
function responsive(config) {
|
|
1904
|
+
const classes = [];
|
|
1905
|
+
if (config.default) {
|
|
1906
|
+
classes.push(config.default);
|
|
1907
|
+
}
|
|
1908
|
+
['sm', 'md', 'lg', 'xl', '2xl'].forEach(bp => {
|
|
1909
|
+
if (config[bp]) {
|
|
1910
|
+
classes.push(`${bp}:${config[bp]}`);
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
return classes.join(' ');
|
|
1914
|
+
}
|
|
1915
|
+
/**
|
|
1916
|
+
* Helper para overflow responsive
|
|
1917
|
+
* Maneja el caso común de scroll en mobile, auto en desktop
|
|
1918
|
+
*
|
|
1919
|
+
* @example
|
|
1920
|
+
* overflowResponsive('x', 'scroll', 'auto')
|
|
1921
|
+
* // Returns: 'overflow-x-scroll sm:overflow-x-auto'
|
|
1922
|
+
*/
|
|
1923
|
+
function overflowResponsive(axis, mobile, desktop) {
|
|
1924
|
+
const axisClass = axis === 'both' ? 'overflow' : `overflow-${axis}`;
|
|
1925
|
+
const mobileClass = `${axisClass}-${mobile}`;
|
|
1926
|
+
if (!desktop || desktop === mobile) {
|
|
1927
|
+
return mobileClass;
|
|
1928
|
+
}
|
|
1929
|
+
return `${mobileClass} sm:${axisClass}-${desktop}`;
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Helper para spacing responsive
|
|
1933
|
+
* Útil para padding/margin que necesita ajustarse por breakpoint
|
|
1934
|
+
*
|
|
1935
|
+
* @example
|
|
1936
|
+
* spacingResponsive('px', { default: '4', sm: '6', lg: '8' })
|
|
1937
|
+
* // Returns: 'px-4 sm:px-6 lg:px-8'
|
|
1938
|
+
*/
|
|
1939
|
+
function spacingResponsive(property, values) {
|
|
1940
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1941
|
+
acc[key] = `${property}-${value}`;
|
|
1942
|
+
return acc;
|
|
1943
|
+
}, {}));
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Helper para width responsive
|
|
1947
|
+
*
|
|
1948
|
+
* @example
|
|
1949
|
+
* widthResponsive({ default: 'full', sm: 'auto', lg: '1/2' })
|
|
1950
|
+
* // Returns: 'w-full sm:w-auto lg:w-1/2'
|
|
1951
|
+
*/
|
|
1952
|
+
function widthResponsive(values) {
|
|
1953
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1954
|
+
acc[key] = `w-${value}`;
|
|
1955
|
+
return acc;
|
|
1956
|
+
}, {}));
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Clases comunes para containers responsive
|
|
1960
|
+
* Pensadas para wrappers que contienen contenido que puede desbordar
|
|
1961
|
+
*/
|
|
1962
|
+
const RESPONSIVE_CONTAINER = {
|
|
1963
|
+
// Container con scroll horizontal en mobile, contenido visible en desktop
|
|
1964
|
+
tableWrapper: 'relative w-full overflow-x-auto sm:overflow-x-visible',
|
|
1965
|
+
// Container con padding negativo en mobile para scroll edge-to-edge
|
|
1966
|
+
tableWrapperFullBleed: 'relative w-full -mx-4 px-4 overflow-x-auto sm:mx-0 sm:px-0 sm:overflow-x-visible',
|
|
1967
|
+
// Container con max-width responsive
|
|
1968
|
+
contentWrapper: 'w-full mx-auto px-4 sm:px-6 lg:px-8 max-w-screen-2xl',
|
|
1969
|
+
// Container para modals/dialogs
|
|
1970
|
+
modalWrapper: 'w-full max-w-lg mx-auto px-4 sm:px-0',
|
|
1971
|
+
// Container para forms
|
|
1972
|
+
formWrapper: 'w-full max-w-md mx-auto space-y-4'
|
|
1973
|
+
};
|
|
1974
|
+
/**
|
|
1975
|
+
* Clases comunes para display responsive
|
|
1976
|
+
*/
|
|
1977
|
+
const RESPONSIVE_DISPLAY = {
|
|
1978
|
+
// Ocultar en mobile, mostrar en desktop
|
|
1979
|
+
hideOnMobile: 'hidden sm:block',
|
|
1980
|
+
// Mostrar solo en mobile
|
|
1981
|
+
showOnMobile: 'block sm:hidden',
|
|
1982
|
+
// Stack en mobile, flex en desktop
|
|
1983
|
+
stackToFlex: 'flex flex-col sm:flex-row',
|
|
1984
|
+
// Stack en mobile, grid en desktop
|
|
1985
|
+
stackToGrid: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'
|
|
1986
|
+
};
|
|
1987
|
+
/**
|
|
1988
|
+
* Clases para table responsive strategies
|
|
1989
|
+
*/
|
|
1990
|
+
const TABLE_RESPONSIVE = {
|
|
1991
|
+
// Scroll horizontal (default, más simple)
|
|
1992
|
+
scroll: {
|
|
1993
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
1994
|
+
table: 'w-full min-w-full',
|
|
1995
|
+
cell: 'whitespace-nowrap'
|
|
1996
|
+
},
|
|
1997
|
+
// Permitir wrap del contenido
|
|
1998
|
+
wrap: {
|
|
1999
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2000
|
+
table: 'w-full',
|
|
2001
|
+
cell: 'whitespace-normal break-words'
|
|
2002
|
+
},
|
|
2003
|
+
// Stack en mobile (cada fila se convierte en card)
|
|
2004
|
+
// Requiere lógica adicional en el componente
|
|
2005
|
+
stack: {
|
|
2006
|
+
wrapper: 'relative w-full',
|
|
2007
|
+
table: 'w-full',
|
|
2008
|
+
row: 'block sm:table-row border-b sm:border-b-0',
|
|
2009
|
+
cell: 'block sm:table-cell py-2 sm:py-0 before:content-[attr(data-label)] before:font-medium before:inline-block before:w-32 sm:before:content-none'
|
|
2010
|
+
},
|
|
2011
|
+
// Collapse: ocultar columnas menos importantes en mobile
|
|
2012
|
+
// Se usa con clases de visibility en las columnas específicas
|
|
2013
|
+
collapse: {
|
|
2014
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2015
|
+
table: 'w-full',
|
|
2016
|
+
cell: 'whitespace-nowrap',
|
|
2017
|
+
// Estas clases se aplican a columnas opcionales
|
|
2018
|
+
optionalColumn: 'hidden md:table-cell'
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
2021
|
+
|
|
2022
|
+
/**
|
|
2023
|
+
* Componente base de tabla con soporte responsive
|
|
2024
|
+
*
|
|
2025
|
+
* SIMPLIFICADO: Ya no incluye drag & drop (usar pdm-draggable-table para eso)
|
|
2026
|
+
*
|
|
2027
|
+
* @example
|
|
2028
|
+
* // Tabla simple con scroll horizontal
|
|
2029
|
+
* <pdm-table variant="default">
|
|
2030
|
+
* <thead><tr><th>Name</th><th>Email</th></tr></thead>
|
|
2031
|
+
* <tbody><tr><td>John</td><td>john@example.com</td></tr></tbody>
|
|
2032
|
+
* </pdm-table>
|
|
2033
|
+
*
|
|
2034
|
+
* @example
|
|
2035
|
+
* // Tabla interactiva con wrap en mobile
|
|
2036
|
+
* <pdm-table variant="interactive" responsiveStrategy="wrap">
|
|
2037
|
+
* ...
|
|
2038
|
+
* </pdm-table>
|
|
2039
|
+
*/
|
|
2040
|
+
class PdmTableComponent {
|
|
2041
|
+
constructor() {
|
|
2042
|
+
/**
|
|
2043
|
+
* Variante visual de la tabla
|
|
2044
|
+
* - default: tabla básica sin estilos extra
|
|
2045
|
+
* - data: tabla con bordes y espaciado para data
|
|
2046
|
+
* - interactive: tabla con hover, sticky header y estilos interactivos
|
|
2047
|
+
*/
|
|
2048
|
+
this.variant = 'default';
|
|
2049
|
+
/**
|
|
2050
|
+
* Estrategia responsive para la tabla
|
|
2051
|
+
* - scroll: scroll horizontal en mobile (default, más simple)
|
|
2052
|
+
* - wrap: permite que el contenido haga wrap
|
|
2053
|
+
* - stack: convierte filas en cards en mobile (requiere data-label en celdas)
|
|
2054
|
+
* - collapse: oculta columnas menos importantes en mobile
|
|
2055
|
+
*/
|
|
2056
|
+
this.responsiveStrategy = 'scroll';
|
|
2057
|
+
/**
|
|
2058
|
+
* Clases CSS adicionales para el wrapper
|
|
2059
|
+
*/
|
|
2060
|
+
this.className = '';
|
|
2061
|
+
/**
|
|
2062
|
+
* Si es true, aplica padding negativo en mobile para scroll edge-to-edge
|
|
2063
|
+
* Útil cuando la tabla está dentro de un container con padding
|
|
2064
|
+
*/
|
|
2065
|
+
this.fullBleed = false;
|
|
2066
|
+
}
|
|
2067
|
+
get wrapperClasses() {
|
|
2068
|
+
const baseClasses = ['relative', 'w-full'];
|
|
2069
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
2070
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
2071
|
+
// Full bleed: scroll edge-to-edge en mobile
|
|
2072
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
2073
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
2074
|
+
}
|
|
2075
|
+
return [
|
|
2076
|
+
...baseClasses,
|
|
2077
|
+
...strategyClasses,
|
|
2078
|
+
...variantClasses,
|
|
2079
|
+
this.className
|
|
2080
|
+
].filter(Boolean);
|
|
2081
|
+
}
|
|
2082
|
+
get tableClasses() {
|
|
2083
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
2084
|
+
const variantClasses = this.getVariantTableClasses();
|
|
2085
|
+
const cellClasses = this.getCellClasses();
|
|
2086
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
2087
|
+
}
|
|
2088
|
+
getResponsiveStrategyClasses() {
|
|
2089
|
+
const strategy = TABLE_RESPONSIVE[this.responsiveStrategy];
|
|
2090
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2091
|
+
return ['overflow-x-auto'];
|
|
2092
|
+
}
|
|
2093
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2094
|
+
return ['overflow-x-auto'];
|
|
2095
|
+
}
|
|
2096
|
+
if (this.responsiveStrategy === 'stack') {
|
|
2097
|
+
// Stack requiere lógica en el template, aquí solo el wrapper
|
|
2098
|
+
return [];
|
|
2099
|
+
}
|
|
2100
|
+
if (this.responsiveStrategy === 'collapse') {
|
|
2101
|
+
return ['overflow-x-auto'];
|
|
2102
|
+
}
|
|
2103
|
+
return ['overflow-auto'];
|
|
2104
|
+
}
|
|
2105
|
+
getVariantWrapperClasses() {
|
|
2106
|
+
if (this.variant === 'interactive') {
|
|
2107
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
2108
|
+
}
|
|
2109
|
+
if (this.variant === 'data') {
|
|
2110
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
2111
|
+
}
|
|
2112
|
+
return [];
|
|
2113
|
+
}
|
|
2114
|
+
getVariantTableClasses() {
|
|
2115
|
+
if (this.variant === 'data') {
|
|
2116
|
+
return [
|
|
2117
|
+
'border-collapse',
|
|
2118
|
+
'text-foreground',
|
|
2119
|
+
'[&_thead_tr]:border-b',
|
|
2120
|
+
'[&_thead_tr]:border-border',
|
|
2121
|
+
'[&_tbody_tr]:border-b',
|
|
2122
|
+
'[&_tbody_tr]:border-border',
|
|
2123
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2124
|
+
'[&_th]:h-10',
|
|
2125
|
+
'[&_th]:px-2',
|
|
2126
|
+
'[&_th]:text-left',
|
|
2127
|
+
'[&_th]:align-middle',
|
|
2128
|
+
'[&_th]:font-medium',
|
|
2129
|
+
'[&_td]:p-2',
|
|
2130
|
+
'[&_td]:align-middle'
|
|
2131
|
+
];
|
|
2132
|
+
}
|
|
2133
|
+
if (this.variant === 'interactive') {
|
|
2134
|
+
return [
|
|
2135
|
+
'text-foreground',
|
|
2136
|
+
'[&_thead]:sticky',
|
|
2137
|
+
'[&_thead]:top-0',
|
|
2138
|
+
'[&_thead]:z-10',
|
|
2139
|
+
'[&_thead]:bg-muted/70',
|
|
2140
|
+
'[&_thead_tr]:border-b',
|
|
2141
|
+
'[&_thead_tr]:border-border',
|
|
2142
|
+
'[&_th]:h-12',
|
|
2143
|
+
'[&_th]:px-4',
|
|
2144
|
+
'[&_th]:text-left',
|
|
2145
|
+
'[&_th]:align-middle',
|
|
2146
|
+
'[&_th]:text-sm',
|
|
2147
|
+
'[&_th]:font-medium',
|
|
2148
|
+
'[&_tbody_tr]:border-b',
|
|
2149
|
+
'[&_tbody_tr]:border-border',
|
|
2150
|
+
'[&_tbody_tr]:transition-colors',
|
|
2151
|
+
'[&_tbody_tr:hover]:bg-muted/50',
|
|
2152
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2153
|
+
'[&_td]:h-14',
|
|
2154
|
+
'[&_td]:px-4',
|
|
2155
|
+
'[&_td]:align-middle',
|
|
2156
|
+
'[&_td]:text-sm',
|
|
2157
|
+
'[&_svg]:text-muted-foreground'
|
|
2158
|
+
];
|
|
2159
|
+
}
|
|
2160
|
+
return [];
|
|
2161
|
+
}
|
|
2162
|
+
getCellClasses() {
|
|
2163
|
+
// Manejo responsive de whitespace
|
|
2164
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2165
|
+
// En scroll, permitir wrap en mobile, nowrap en desktop
|
|
2166
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
2167
|
+
}
|
|
2168
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2169
|
+
// En wrap, siempre permitir wrap
|
|
2170
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
2171
|
+
}
|
|
2172
|
+
// Default: nowrap (comportamiento anterior para backward compatibility)
|
|
2173
|
+
return [];
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2177
|
+
PdmTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTableComponent, selector: "pdm-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed" }, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
2179
|
+
type: Component,
|
|
2180
|
+
args: [{ selector: 'pdm-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
|
|
2181
|
+
}], propDecorators: { variant: [{
|
|
2182
|
+
type: Input
|
|
2183
|
+
}], responsiveStrategy: [{
|
|
2184
|
+
type: Input
|
|
2185
|
+
}], className: [{
|
|
2186
|
+
type: Input
|
|
2187
|
+
}], fullBleed: [{
|
|
2188
|
+
type: Input
|
|
2189
|
+
}] } });
|
|
2190
|
+
|
|
2191
|
+
/**
|
|
2192
|
+
* Data-table genérico con paginación, filtrado y selección
|
|
2193
|
+
*
|
|
2194
|
+
* NUEVO: Ahora es genérico y configurable via columnas
|
|
2195
|
+
*
|
|
2196
|
+
* @example
|
|
2197
|
+
* // Definir columnas
|
|
2198
|
+
* columns: PdmDataTableColumn<User>[] = [
|
|
2199
|
+
* { key: 'name', label: 'Name', sortable: true },
|
|
2200
|
+
* { key: 'email', label: 'Email', sortable: true },
|
|
2201
|
+
* { key: 'role', label: 'Role', hideOnMobile: true },
|
|
2202
|
+
* { key: 'createdAt', label: 'Created', render: (val) => formatDate(val) }
|
|
2203
|
+
* ];
|
|
2204
|
+
*
|
|
2205
|
+
* // En el template
|
|
2206
|
+
* <pdm-data-table
|
|
2207
|
+
* [columns]="columns"
|
|
2208
|
+
* [rows]="users"
|
|
2209
|
+
* [selectable]="true"
|
|
2210
|
+
* (selectionChange)="onSelect($event)">
|
|
2211
|
+
* </pdm-data-table>
|
|
2212
|
+
*/
|
|
1863
2213
|
class PdmDataTableComponent {
|
|
1864
2214
|
constructor() {
|
|
1865
2215
|
this.className = '';
|
|
2216
|
+
/**
|
|
2217
|
+
* Columnas a mostrar
|
|
2218
|
+
* Si no se provee, intenta inferir del primer row (legacy mode)
|
|
2219
|
+
*/
|
|
2220
|
+
this.columns = [];
|
|
2221
|
+
/**
|
|
2222
|
+
* Estrategia responsive de la tabla
|
|
2223
|
+
*/
|
|
2224
|
+
this.responsiveStrategy = 'scroll';
|
|
2225
|
+
/**
|
|
2226
|
+
* Si es true, muestra checkbox de selección en cada fila
|
|
2227
|
+
*/
|
|
2228
|
+
this.selectable = false;
|
|
2229
|
+
/**
|
|
2230
|
+
* Si es true, muestra botón de acciones (tres puntos) en cada fila
|
|
2231
|
+
*/
|
|
2232
|
+
this.showActions = false;
|
|
2233
|
+
/**
|
|
2234
|
+
* Si es true, muestra filtro de búsqueda
|
|
2235
|
+
*/
|
|
2236
|
+
this.showFilter = true;
|
|
2237
|
+
/**
|
|
2238
|
+
* Si es true, muestra controles de paginación
|
|
2239
|
+
*/
|
|
2240
|
+
this.showPagination = true;
|
|
2241
|
+
/**
|
|
2242
|
+
* Si es true, muestra selector de columnas
|
|
2243
|
+
*/
|
|
2244
|
+
this.showColumnSelector = false;
|
|
2245
|
+
// Labels i18n
|
|
1866
2246
|
this.filterPlaceholder = 'Filter...';
|
|
1867
2247
|
this.columnsLabel = 'Columns';
|
|
1868
|
-
this.statusLabel = 'Status';
|
|
1869
|
-
this.emailLabel = 'Email';
|
|
1870
|
-
this.amountLabel = 'Amount';
|
|
1871
2248
|
this.previousLabel = 'Previous';
|
|
1872
2249
|
this.nextLabel = 'Next';
|
|
1873
2250
|
this.emptyLabel = 'No results.';
|
|
2251
|
+
this.rowsSelectedLabel = 'row(s) selected';
|
|
2252
|
+
// DEPRECATED: Labels hardcodeados para backward compatibility
|
|
2253
|
+
/**
|
|
2254
|
+
* @deprecated Use columns configuration instead
|
|
2255
|
+
*/
|
|
2256
|
+
this.statusLabel = 'Status';
|
|
2257
|
+
/**
|
|
2258
|
+
* @deprecated Use columns configuration instead
|
|
2259
|
+
*/
|
|
2260
|
+
this.emailLabel = 'Email';
|
|
2261
|
+
/**
|
|
2262
|
+
* @deprecated Use columns configuration instead
|
|
2263
|
+
*/
|
|
2264
|
+
this.amountLabel = 'Amount';
|
|
2265
|
+
/**
|
|
2266
|
+
* Datos a mostrar
|
|
2267
|
+
*/
|
|
1874
2268
|
this.rows = [];
|
|
2269
|
+
/**
|
|
2270
|
+
* Página actual (1-indexed)
|
|
2271
|
+
*/
|
|
1875
2272
|
this.page = 1;
|
|
1876
|
-
|
|
2273
|
+
/**
|
|
2274
|
+
* Cantidad de filas por página
|
|
2275
|
+
*/
|
|
2276
|
+
this.pageSize = 10;
|
|
2277
|
+
/**
|
|
2278
|
+
* Query de filtrado
|
|
2279
|
+
*/
|
|
1877
2280
|
this.query = '';
|
|
1878
2281
|
this.queryChange = new EventEmitter();
|
|
1879
2282
|
this.rowAction = new EventEmitter();
|
|
1880
2283
|
this.pageChange = new EventEmitter();
|
|
1881
2284
|
this.selectionChange = new EventEmitter();
|
|
2285
|
+
this.columnSort = new EventEmitter();
|
|
2286
|
+
// Estado interno
|
|
2287
|
+
this.selectedRows = new Set();
|
|
2288
|
+
this.sortDirection = 'asc';
|
|
2289
|
+
}
|
|
2290
|
+
/**
|
|
2291
|
+
* Backward compatibility: si no hay columnas definidas, inferir del primer row
|
|
2292
|
+
*/
|
|
2293
|
+
get effectiveColumns() {
|
|
2294
|
+
if (this.columns.length > 0) {
|
|
2295
|
+
return this.columns;
|
|
2296
|
+
}
|
|
2297
|
+
// Legacy mode: inferir columnas del primer row (solo para PdmDataTableRow)
|
|
2298
|
+
if (this.rows.length > 0) {
|
|
2299
|
+
const firstRow = this.rows[0];
|
|
2300
|
+
return Object.keys(firstRow)
|
|
2301
|
+
.filter(key => key !== 'selected')
|
|
2302
|
+
.map(key => ({
|
|
2303
|
+
key: key,
|
|
2304
|
+
label: this.getLegacyLabel(key),
|
|
2305
|
+
align: key === 'amount' ? 'right' : 'left'
|
|
2306
|
+
}));
|
|
2307
|
+
}
|
|
2308
|
+
return [];
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* LEGACY: mapeo de keys a labels hardcodeados
|
|
2312
|
+
*/
|
|
2313
|
+
getLegacyLabel(key) {
|
|
2314
|
+
const map = {
|
|
2315
|
+
status: this.statusLabel,
|
|
2316
|
+
email: this.emailLabel,
|
|
2317
|
+
amount: this.amountLabel
|
|
2318
|
+
};
|
|
2319
|
+
return map[key] || key.charAt(0).toUpperCase() + key.slice(1);
|
|
1882
2320
|
}
|
|
1883
2321
|
get filteredRows() {
|
|
1884
2322
|
const q = this.query.trim().toLowerCase();
|
|
1885
2323
|
if (!q)
|
|
1886
2324
|
return this.rows;
|
|
1887
|
-
|
|
2325
|
+
if (this.filterFn) {
|
|
2326
|
+
return this.rows.filter(row => this.filterFn(row, q));
|
|
2327
|
+
}
|
|
2328
|
+
// Filtrado default: buscar en todos los campos string
|
|
2329
|
+
return this.rows.filter(row => {
|
|
2330
|
+
return Object.values(row).some(val => typeof val === 'string' && val.toLowerCase().includes(q));
|
|
2331
|
+
});
|
|
1888
2332
|
}
|
|
1889
2333
|
get pagedRows() {
|
|
1890
2334
|
const start = (this.page - 1) * this.pageSize;
|
|
@@ -1894,14 +2338,33 @@ class PdmDataTableComponent {
|
|
|
1894
2338
|
return Math.max(1, Math.ceil(this.filteredRows.length / this.pageSize));
|
|
1895
2339
|
}
|
|
1896
2340
|
get selectedCount() {
|
|
1897
|
-
return this.
|
|
2341
|
+
return this.selectedRows.size;
|
|
1898
2342
|
}
|
|
1899
2343
|
onQueryInput(event) {
|
|
1900
2344
|
const value = event.target.value;
|
|
1901
2345
|
this.queryChange.emit(value);
|
|
1902
2346
|
}
|
|
1903
2347
|
onToggleRow(row, event) {
|
|
1904
|
-
|
|
2348
|
+
const checked = event.target.checked;
|
|
2349
|
+
if (checked) {
|
|
2350
|
+
this.selectedRows.add(row);
|
|
2351
|
+
}
|
|
2352
|
+
else {
|
|
2353
|
+
this.selectedRows.delete(row);
|
|
2354
|
+
}
|
|
2355
|
+
this.selectionChange.emit({ row, selected: checked });
|
|
2356
|
+
}
|
|
2357
|
+
onToggleAll(event) {
|
|
2358
|
+
const checked = event.target.checked;
|
|
2359
|
+
if (checked) {
|
|
2360
|
+
this.pagedRows.forEach(row => this.selectedRows.add(row));
|
|
2361
|
+
}
|
|
2362
|
+
else {
|
|
2363
|
+
this.pagedRows.forEach(row => this.selectedRows.delete(row));
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
isSelected(row) {
|
|
2367
|
+
return this.selectedRows.has(row);
|
|
1905
2368
|
}
|
|
1906
2369
|
previous() {
|
|
1907
2370
|
if (this.page <= 1)
|
|
@@ -1914,25 +2377,75 @@ class PdmDataTableComponent {
|
|
|
1914
2377
|
this.pageChange.emit(this.page + 1);
|
|
1915
2378
|
}
|
|
1916
2379
|
onAction(row) {
|
|
1917
|
-
this.rowAction.emit(row
|
|
2380
|
+
this.rowAction.emit(row);
|
|
2381
|
+
}
|
|
2382
|
+
onSort(column) {
|
|
2383
|
+
if (!column.sortable)
|
|
2384
|
+
return;
|
|
2385
|
+
if (this.sortColumn === column) {
|
|
2386
|
+
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
|
2387
|
+
}
|
|
2388
|
+
else {
|
|
2389
|
+
this.sortColumn = column;
|
|
2390
|
+
this.sortDirection = 'asc';
|
|
2391
|
+
}
|
|
2392
|
+
this.columnSort.emit({ column, direction: this.sortDirection });
|
|
2393
|
+
}
|
|
2394
|
+
getCellValue(row, column) {
|
|
2395
|
+
const value = row[column.key];
|
|
2396
|
+
if (column.render) {
|
|
2397
|
+
return column.render(value, row);
|
|
2398
|
+
}
|
|
2399
|
+
return value != null ? String(value) : '';
|
|
2400
|
+
}
|
|
2401
|
+
getCellClass(column) {
|
|
2402
|
+
const classes = ['px-2', 'py-2'];
|
|
2403
|
+
if (column.align === 'center')
|
|
2404
|
+
classes.push('text-center');
|
|
2405
|
+
if (column.align === 'right')
|
|
2406
|
+
classes.push('text-right');
|
|
2407
|
+
if (column.hideOnMobile)
|
|
2408
|
+
classes.push('hidden', 'md:table-cell');
|
|
2409
|
+
if (column.cellClass)
|
|
2410
|
+
classes.push(column.cellClass);
|
|
2411
|
+
return classes.join(' ');
|
|
2412
|
+
}
|
|
2413
|
+
getHeaderClass(column) {
|
|
2414
|
+
const classes = ['px-2', 'py-2', 'text-left', 'font-medium'];
|
|
2415
|
+
if (column.hideOnMobile)
|
|
2416
|
+
classes.push('hidden', 'md:table-cell');
|
|
2417
|
+
if (column.headerClass)
|
|
2418
|
+
classes.push(column.headerClass);
|
|
2419
|
+
return classes.join(' ');
|
|
2420
|
+
}
|
|
2421
|
+
getColumnStyle(column) {
|
|
2422
|
+
return column.width ? { width: column.width } : {};
|
|
1918
2423
|
}
|
|
1919
2424
|
}
|
|
1920
2425
|
PdmDataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1921
|
-
PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className",
|
|
2426
|
+
PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className", columns: "columns", responsiveStrategy: "responsiveStrategy", selectable: "selectable", showActions: "showActions", showFilter: "showFilter", showPagination: "showPagination", showColumnSelector: "showColumnSelector", filterPlaceholder: "filterPlaceholder", columnsLabel: "columnsLabel", previousLabel: "previousLabel", nextLabel: "nextLabel", emptyLabel: "emptyLabel", rowsSelectedLabel: "rowsSelectedLabel", statusLabel: "statusLabel", emailLabel: "emailLabel", amountLabel: "amountLabel", rows: "rows", page: "page", pageSize: "pageSize", query: "query", filterFn: "filterFn" }, outputs: { queryChange: "queryChange", rowAction: "rowAction", pageChange: "pageChange", selectionChange: "selectionChange", columnSort: "columnSort" }, ngImport: i0, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PdmTableComponent, selector: "pdm-table", inputs: ["variant", "responsiveStrategy", "className", "fullBleed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1922
2427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, decorators: [{
|
|
1923
2428
|
type: Component,
|
|
1924
|
-
args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full
|
|
2429
|
+
args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n" }]
|
|
1925
2430
|
}], propDecorators: { className: [{
|
|
1926
2431
|
type: Input
|
|
1927
|
-
}],
|
|
2432
|
+
}], columns: [{
|
|
1928
2433
|
type: Input
|
|
1929
|
-
}],
|
|
2434
|
+
}], responsiveStrategy: [{
|
|
1930
2435
|
type: Input
|
|
1931
|
-
}],
|
|
2436
|
+
}], selectable: [{
|
|
1932
2437
|
type: Input
|
|
1933
|
-
}],
|
|
2438
|
+
}], showActions: [{
|
|
1934
2439
|
type: Input
|
|
1935
|
-
}],
|
|
2440
|
+
}], showFilter: [{
|
|
2441
|
+
type: Input
|
|
2442
|
+
}], showPagination: [{
|
|
2443
|
+
type: Input
|
|
2444
|
+
}], showColumnSelector: [{
|
|
2445
|
+
type: Input
|
|
2446
|
+
}], filterPlaceholder: [{
|
|
2447
|
+
type: Input
|
|
2448
|
+
}], columnsLabel: [{
|
|
1936
2449
|
type: Input
|
|
1937
2450
|
}], previousLabel: [{
|
|
1938
2451
|
type: Input
|
|
@@ -1940,6 +2453,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1940
2453
|
type: Input
|
|
1941
2454
|
}], emptyLabel: [{
|
|
1942
2455
|
type: Input
|
|
2456
|
+
}], rowsSelectedLabel: [{
|
|
2457
|
+
type: Input
|
|
2458
|
+
}], statusLabel: [{
|
|
2459
|
+
type: Input
|
|
2460
|
+
}], emailLabel: [{
|
|
2461
|
+
type: Input
|
|
2462
|
+
}], amountLabel: [{
|
|
2463
|
+
type: Input
|
|
1943
2464
|
}], rows: [{
|
|
1944
2465
|
type: Input
|
|
1945
2466
|
}], page: [{
|
|
@@ -1948,6 +2469,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1948
2469
|
type: Input
|
|
1949
2470
|
}], query: [{
|
|
1950
2471
|
type: Input
|
|
2472
|
+
}], filterFn: [{
|
|
2473
|
+
type: Input
|
|
1951
2474
|
}], queryChange: [{
|
|
1952
2475
|
type: Output
|
|
1953
2476
|
}], rowAction: [{
|
|
@@ -1956,6 +2479,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1956
2479
|
type: Output
|
|
1957
2480
|
}], selectionChange: [{
|
|
1958
2481
|
type: Output
|
|
2482
|
+
}], columnSort: [{
|
|
2483
|
+
type: Output
|
|
1959
2484
|
}] } });
|
|
1960
2485
|
|
|
1961
2486
|
/**
|
|
@@ -2373,30 +2898,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2373
2898
|
args: ['document:keydown.escape']
|
|
2374
2899
|
}] } });
|
|
2375
2900
|
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2901
|
+
/**
|
|
2902
|
+
* Z-Index Scale - Sistema centralizado de z-index
|
|
2903
|
+
*
|
|
2904
|
+
* JERARQUÍA (de menor a mayor):
|
|
2905
|
+
* 1. base (z-0) - Elementos normales del DOM
|
|
2906
|
+
* 2. dropdown (z-10) - Selects, combobox, date-pickers
|
|
2907
|
+
* 3. sticky (z-20) - Headers, navigation bars
|
|
2908
|
+
* 4. overlay (z-30) - Popovers, hover cards, context menus
|
|
2909
|
+
* 5. drawer (z-40) - Sidebar drawer, sheets laterales
|
|
2910
|
+
* 6. modal (z-50) - Dialogs, alert-dialogs
|
|
2911
|
+
* 7. modal-backdrop (z-40) - Backdrop de modals
|
|
2912
|
+
* 8. popover (z-60) - Tooltips, dropdowns DENTRO de modals
|
|
2913
|
+
* 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO
|
|
2914
|
+
*
|
|
2915
|
+
* REGLA CRÍTICA:
|
|
2916
|
+
* - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-60 o mayor
|
|
2917
|
+
* - Esto permite que funcionen DENTRO de modals (z-50)
|
|
2918
|
+
* - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)
|
|
2919
|
+
*/
|
|
2920
|
+
const Z_INDEX = {
|
|
2921
|
+
/**
|
|
2922
|
+
* Base - contenido normal del DOM
|
|
2923
|
+
*/
|
|
2924
|
+
base: 'z-0',
|
|
2925
|
+
/**
|
|
2926
|
+
* Dropdown - Selects, combobox, date-pickers
|
|
2927
|
+
* Debe estar SOBRE contenido normal pero BAJO modals
|
|
2928
|
+
*/
|
|
2929
|
+
dropdown: 'z-10',
|
|
2930
|
+
/**
|
|
2931
|
+
* Sticky - Headers, navigation fija
|
|
2932
|
+
*/
|
|
2933
|
+
sticky: 'z-20',
|
|
2934
|
+
/**
|
|
2935
|
+
* Overlay - Popovers, hover cards, context menus
|
|
2936
|
+
* Debe estar SOBRE sticky pero BAJO modals
|
|
2937
|
+
*/
|
|
2938
|
+
overlay: 'z-30',
|
|
2939
|
+
/**
|
|
2940
|
+
* Drawer backdrop - Backdrop de sidebar drawer
|
|
2941
|
+
* Debe estar DEBAJO del drawer panel
|
|
2942
|
+
*/
|
|
2943
|
+
drawerBackdrop: 'z-40',
|
|
2944
|
+
/**
|
|
2945
|
+
* Drawer - Sidebar drawer, sheets laterales
|
|
2946
|
+
* Debe estar SOBRE su backdrop pero BAJO modals
|
|
2947
|
+
*/
|
|
2948
|
+
drawer: 'z-50',
|
|
2949
|
+
/**
|
|
2950
|
+
* Modal backdrop - Backdrop de dialogs
|
|
2951
|
+
* Debe estar SOBRE drawers pero DEBAJO del contenido del modal
|
|
2952
|
+
*/
|
|
2953
|
+
modalBackdrop: 'z-50',
|
|
2954
|
+
/**
|
|
2955
|
+
* Modal - Dialogs, alert-dialogs, sheets
|
|
2956
|
+
* Debe estar SOBRE su backdrop
|
|
2957
|
+
*/
|
|
2958
|
+
modal: 'z-[60]',
|
|
2959
|
+
/**
|
|
2960
|
+
* Popover - Tooltips, dropdowns, selects options DENTRO de modals
|
|
2961
|
+
* CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals
|
|
2962
|
+
*/
|
|
2963
|
+
popover: 'z-[70]',
|
|
2964
|
+
/**
|
|
2965
|
+
* Toast - Notificaciones globales
|
|
2966
|
+
* Debe estar sobre TODO
|
|
2967
|
+
*/
|
|
2968
|
+
toast: 'z-[100]'
|
|
2969
|
+
};
|
|
2970
|
+
/**
|
|
2971
|
+
* Helper para debugging z-index issues
|
|
2972
|
+
*/
|
|
2973
|
+
function logZIndexStack(element) {
|
|
2974
|
+
if (typeof window === 'undefined')
|
|
2975
|
+
return;
|
|
2976
|
+
let current = element;
|
|
2977
|
+
const stack = [];
|
|
2978
|
+
while (current && current !== document.body) {
|
|
2979
|
+
const computed = window.getComputedStyle(current);
|
|
2980
|
+
const zIndex = computed.zIndex;
|
|
2981
|
+
const position = computed.position;
|
|
2982
|
+
if (zIndex !== 'auto') {
|
|
2983
|
+
stack.push({
|
|
2984
|
+
element: current.tagName + (current.className ? `.${current.className.split(' ')[0]}` : ''),
|
|
2985
|
+
zIndex,
|
|
2986
|
+
position
|
|
2987
|
+
});
|
|
2988
|
+
}
|
|
2989
|
+
current = current.parentElement;
|
|
2990
|
+
}
|
|
2991
|
+
console.table(stack);
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
/**
|
|
2995
|
+
* Modal/Dialog component con soporte responsive
|
|
2996
|
+
*
|
|
2997
|
+
* MEJORADO en v0.2.0:
|
|
2998
|
+
* - Modo 'responsive' (default): fullscreen en mobile, modal en desktop
|
|
2999
|
+
* - Tamaños predefinidos: sm, md, lg, xl
|
|
3000
|
+
* - Mejor manejo de scroll en mobile
|
|
3001
|
+
*
|
|
3002
|
+
* @example
|
|
3003
|
+
* // Responsive (recomendado)
|
|
3004
|
+
* <pdm-dialog [open]="isOpen" size="responsive">
|
|
3005
|
+
* <p>Content</p>
|
|
3006
|
+
* </pdm-dialog>
|
|
3007
|
+
*
|
|
3008
|
+
* @example
|
|
3009
|
+
* // Tamaño fijo
|
|
3010
|
+
* <pdm-dialog [open]="isOpen" size="lg">
|
|
3011
|
+
* <p>Content</p>
|
|
3012
|
+
* </pdm-dialog>
|
|
3013
|
+
*/
|
|
3014
|
+
class PdmDialogComponent {
|
|
3015
|
+
constructor() {
|
|
3016
|
+
this.open = false;
|
|
3017
|
+
this.variant = 'default';
|
|
3018
|
+
/**
|
|
3019
|
+
* Tamaño del dialog
|
|
3020
|
+
* - responsive: fullscreen mobile, modal desktop (recomendado)
|
|
3021
|
+
* - sm: 400px max
|
|
3022
|
+
* - md: 500px max
|
|
3023
|
+
* - lg: 640px max (default)
|
|
3024
|
+
* - xl: 800px max
|
|
3025
|
+
* - desktop/mobile/mobile-fullscreen: legacy, deprecado
|
|
3026
|
+
*/
|
|
3027
|
+
this.size = 'responsive';
|
|
3028
|
+
this.title = 'Edit profile';
|
|
3029
|
+
this.description = '';
|
|
3030
|
+
this.closeOnBackdrop = true;
|
|
3031
|
+
this.closeOnEsc = true;
|
|
3032
|
+
this.showCloseButton = true;
|
|
3033
|
+
this.showHeader = true;
|
|
3034
|
+
this.showFooter = true;
|
|
3035
|
+
this.primaryActionText = 'Save changes';
|
|
3036
|
+
this.secondaryActionText = 'Cancel';
|
|
3037
|
+
this.alignFooter = 'right';
|
|
3038
|
+
this.headerClassName = '';
|
|
3039
|
+
this.bodyClassName = '';
|
|
3040
|
+
this.footerClassName = '';
|
|
3041
|
+
this.className = '';
|
|
3042
|
+
this.openChange = new EventEmitter();
|
|
3043
|
+
this.primaryAction = new EventEmitter();
|
|
3044
|
+
this.secondaryAction = new EventEmitter();
|
|
3045
|
+
}
|
|
3046
|
+
onEsc() {
|
|
2400
3047
|
if (this.open && this.closeOnEsc) {
|
|
2401
3048
|
this.close();
|
|
2402
3049
|
}
|
|
@@ -2416,47 +3063,132 @@ class PdmDialogComponent {
|
|
|
2416
3063
|
}
|
|
2417
3064
|
}
|
|
2418
3065
|
get panelClassName() {
|
|
3066
|
+
// Legacy sizes (backward compatibility)
|
|
3067
|
+
if (this.size === 'desktop') {
|
|
3068
|
+
return this.buildClasses(['max-w-[640px]', 'max-h-[calc(100vh-2rem)]', 'rounded-[10px]']);
|
|
3069
|
+
}
|
|
3070
|
+
if (this.size === 'mobile') {
|
|
3071
|
+
return this.buildClasses(['max-w-[320px]', 'min-h-[240px]', 'rounded-[10px]']);
|
|
3072
|
+
}
|
|
3073
|
+
if (this.size === 'mobile-fullscreen') {
|
|
3074
|
+
return this.buildClasses(['max-w-[320px]', 'h-[min(100dvh,640px)]', 'rounded-none', 'sm:rounded-[10px]']);
|
|
3075
|
+
}
|
|
3076
|
+
// New responsive mode (recomendado)
|
|
3077
|
+
if (this.size === 'responsive') {
|
|
3078
|
+
return this.buildClasses([
|
|
3079
|
+
// Mobile: fullscreen con bordes redondeados solo arriba
|
|
3080
|
+
'w-full',
|
|
3081
|
+
'h-full',
|
|
3082
|
+
'max-h-[100dvh]',
|
|
3083
|
+
'rounded-t-[10px]',
|
|
3084
|
+
'sm:rounded-[10px]',
|
|
3085
|
+
// Desktop: modal centrado
|
|
3086
|
+
'sm:w-auto',
|
|
3087
|
+
'sm:h-auto',
|
|
3088
|
+
'sm:max-w-[640px]',
|
|
3089
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3090
|
+
]);
|
|
3091
|
+
}
|
|
3092
|
+
// New size options
|
|
3093
|
+
const sizeMap = {
|
|
3094
|
+
sm: 'sm:max-w-[400px]',
|
|
3095
|
+
md: 'sm:max-w-[500px]',
|
|
3096
|
+
lg: 'sm:max-w-[640px]',
|
|
3097
|
+
xl: 'sm:max-w-[800px]'
|
|
3098
|
+
};
|
|
3099
|
+
const maxWidth = sizeMap[this.size] || sizeMap.lg;
|
|
3100
|
+
return this.buildClasses([
|
|
3101
|
+
// Mobile: fullscreen
|
|
3102
|
+
'w-full',
|
|
3103
|
+
'h-full',
|
|
3104
|
+
'max-h-[100dvh]',
|
|
3105
|
+
'rounded-t-[10px]',
|
|
3106
|
+
// Desktop: modal
|
|
3107
|
+
'sm:rounded-[10px]',
|
|
3108
|
+
'sm:w-auto',
|
|
3109
|
+
'sm:h-auto',
|
|
3110
|
+
maxWidth,
|
|
3111
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3112
|
+
]);
|
|
3113
|
+
}
|
|
3114
|
+
buildClasses(sizeClasses) {
|
|
2419
3115
|
const base = [
|
|
2420
|
-
'relative
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
3116
|
+
'relative',
|
|
3117
|
+
Z_INDEX.modal,
|
|
3118
|
+
'flex',
|
|
3119
|
+
'flex-col',
|
|
3120
|
+
'border',
|
|
3121
|
+
'border-border',
|
|
3122
|
+
'bg-background',
|
|
3123
|
+
'text-foreground',
|
|
3124
|
+
'shadow-lg',
|
|
3125
|
+
'overflow-hidden',
|
|
3126
|
+
...sizeClasses,
|
|
2426
3127
|
this.className
|
|
2427
3128
|
];
|
|
2428
3129
|
return base.filter(Boolean).join(' ');
|
|
2429
3130
|
}
|
|
2430
3131
|
get bodyWrapperClassName() {
|
|
2431
3132
|
const base = [
|
|
2432
|
-
'
|
|
2433
|
-
|
|
3133
|
+
'flex-1',
|
|
3134
|
+
'overflow-y-auto',
|
|
3135
|
+
'px-4',
|
|
3136
|
+
'py-6',
|
|
3137
|
+
'sm:px-6',
|
|
2434
3138
|
this.bodyClassName
|
|
2435
3139
|
];
|
|
2436
3140
|
return base.filter(Boolean).join(' ');
|
|
2437
3141
|
}
|
|
2438
3142
|
get headerWrapperClassName() {
|
|
2439
|
-
|
|
3143
|
+
const base = [
|
|
3144
|
+
'flex',
|
|
3145
|
+
'items-start',
|
|
3146
|
+
'justify-between',
|
|
3147
|
+
'gap-3',
|
|
3148
|
+
'p-4',
|
|
3149
|
+
'sm:p-6',
|
|
3150
|
+
'border-b',
|
|
3151
|
+
'border-border',
|
|
3152
|
+
this.headerClassName
|
|
3153
|
+
];
|
|
3154
|
+
return base.filter(Boolean).join(' ');
|
|
2440
3155
|
}
|
|
2441
3156
|
get footerWrapperClassName() {
|
|
2442
3157
|
const effectiveAlign = this.alignFooter === 'right' && this.variant === 'custom-close' ? 'left' : this.alignFooter;
|
|
2443
3158
|
const base = [
|
|
2444
3159
|
'p-4',
|
|
3160
|
+
'sm:p-6',
|
|
3161
|
+
'border-t',
|
|
3162
|
+
'border-border',
|
|
3163
|
+
// Mobile: siempre full-width
|
|
3164
|
+
'flex',
|
|
3165
|
+
'flex-col',
|
|
3166
|
+
'gap-2',
|
|
3167
|
+
// Desktop: según alignFooter
|
|
2445
3168
|
effectiveAlign === 'full-width'
|
|
2446
|
-
? 'flex
|
|
2447
|
-
:
|
|
2448
|
-
|
|
2449
|
-
|
|
3169
|
+
? 'sm:flex-col'
|
|
3170
|
+
: 'sm:flex-row sm:items-center',
|
|
3171
|
+
effectiveAlign === 'left' ? 'sm:justify-start' : '',
|
|
3172
|
+
effectiveAlign === 'right' ? 'sm:justify-end' : '',
|
|
2450
3173
|
this.footerClassName
|
|
2451
3174
|
];
|
|
2452
3175
|
return base.filter(Boolean).join(' ');
|
|
2453
3176
|
}
|
|
3177
|
+
get containerClassName() {
|
|
3178
|
+
// Container con backdrop z-50
|
|
3179
|
+
// Mobile: fullscreen desde el bottom
|
|
3180
|
+
// Desktop: centrado
|
|
3181
|
+
return responsive({
|
|
3182
|
+
default: `fixed inset-x-0 bottom-0 ${Z_INDEX.modalBackdrop} flex items-end justify-center`,
|
|
3183
|
+
sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`
|
|
3184
|
+
});
|
|
3185
|
+
}
|
|
2454
3186
|
}
|
|
2455
3187
|
PdmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2456
|
-
PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\"
|
|
3188
|
+
PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2457
3189
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, decorators: [{
|
|
2458
3190
|
type: Component,
|
|
2459
|
-
args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3191
|
+
args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n" }]
|
|
2460
3192
|
}], propDecorators: { open: [{
|
|
2461
3193
|
type: Input
|
|
2462
3194
|
}], variant: [{
|
|
@@ -2502,6 +3234,303 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2502
3234
|
args: ['document:keydown.escape']
|
|
2503
3235
|
}] } });
|
|
2504
3236
|
|
|
3237
|
+
/**
|
|
3238
|
+
* Tabla con funcionalidad de reordenamiento de filas mediante drag & drop
|
|
3239
|
+
*
|
|
3240
|
+
* Extiende pdm-table agregando la capacidad de reordenar filas.
|
|
3241
|
+
* Si no necesitás drag & drop, usá pdm-table directamente (más simple y liviano).
|
|
3242
|
+
*
|
|
3243
|
+
* @example
|
|
3244
|
+
* <pdm-draggable-table
|
|
3245
|
+
* variant="interactive"
|
|
3246
|
+
* [reorderRows]="true"
|
|
3247
|
+
* (rowOrderChange)="onOrderChange($event)">
|
|
3248
|
+
* <tbody>
|
|
3249
|
+
* <tr data-row-id="1"><td>Row 1</td></tr>
|
|
3250
|
+
* <tr data-row-id="2"><td>Row 2</td></tr>
|
|
3251
|
+
* </tbody>
|
|
3252
|
+
* </pdm-draggable-table>
|
|
3253
|
+
*
|
|
3254
|
+
* IMPORTANTE: Cada <tr> debe tener un atributo data-row-id único
|
|
3255
|
+
*/
|
|
3256
|
+
class PdmDraggableTableComponent {
|
|
3257
|
+
constructor(renderer) {
|
|
3258
|
+
this.renderer = renderer;
|
|
3259
|
+
this.variant = 'default';
|
|
3260
|
+
this.responsiveStrategy = 'scroll';
|
|
3261
|
+
this.className = '';
|
|
3262
|
+
this.fullBleed = false;
|
|
3263
|
+
/**
|
|
3264
|
+
* Habilita el reordenamiento de filas mediante drag & drop
|
|
3265
|
+
*/
|
|
3266
|
+
this.reorderRows = false;
|
|
3267
|
+
/**
|
|
3268
|
+
* Selector CSS para identificar los handles de drag
|
|
3269
|
+
* Por defecto busca: [data-drag-handle], [data-slot=row-drag-handle], .row-drag-handle
|
|
3270
|
+
* Si no encuentra ninguno, inserta un handle automático
|
|
3271
|
+
*/
|
|
3272
|
+
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
3273
|
+
/**
|
|
3274
|
+
* Emite el nuevo orden de las filas cuando el usuario termina de arrastrar
|
|
3275
|
+
* Array de data-row-id en el nuevo orden
|
|
3276
|
+
*/
|
|
3277
|
+
this.rowOrderChange = new EventEmitter();
|
|
3278
|
+
this.cleanupListeners = [];
|
|
3279
|
+
this.draggedRow = null;
|
|
3280
|
+
}
|
|
3281
|
+
ngAfterViewInit() {
|
|
3282
|
+
this.syncReorderBehavior();
|
|
3283
|
+
}
|
|
3284
|
+
// Getters para clases CSS (mismo comportamiento que pdm-table)
|
|
3285
|
+
get wrapperClasses() {
|
|
3286
|
+
const baseClasses = ['relative', 'w-full'];
|
|
3287
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
3288
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
3289
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
3290
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
3291
|
+
}
|
|
3292
|
+
return [
|
|
3293
|
+
...baseClasses,
|
|
3294
|
+
...strategyClasses,
|
|
3295
|
+
...variantClasses,
|
|
3296
|
+
this.className
|
|
3297
|
+
].filter(Boolean);
|
|
3298
|
+
}
|
|
3299
|
+
get tableClasses() {
|
|
3300
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
3301
|
+
const variantClasses = this.getVariantTableClasses();
|
|
3302
|
+
const cellClasses = this.getCellClasses();
|
|
3303
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
3304
|
+
}
|
|
3305
|
+
getResponsiveStrategyClasses() {
|
|
3306
|
+
if (this.responsiveStrategy === 'scroll' || this.responsiveStrategy === 'wrap' || this.responsiveStrategy === 'collapse') {
|
|
3307
|
+
return ['overflow-x-auto'];
|
|
3308
|
+
}
|
|
3309
|
+
return [];
|
|
3310
|
+
}
|
|
3311
|
+
getVariantWrapperClasses() {
|
|
3312
|
+
if (this.variant === 'interactive') {
|
|
3313
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
3314
|
+
}
|
|
3315
|
+
if (this.variant === 'data') {
|
|
3316
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
3317
|
+
}
|
|
3318
|
+
return [];
|
|
3319
|
+
}
|
|
3320
|
+
getVariantTableClasses() {
|
|
3321
|
+
if (this.variant === 'data') {
|
|
3322
|
+
return [
|
|
3323
|
+
'border-collapse', 'text-foreground',
|
|
3324
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3325
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3326
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3327
|
+
'[&_th]:h-10', '[&_th]:px-2', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:font-medium',
|
|
3328
|
+
'[&_td]:p-2', '[&_td]:align-middle'
|
|
3329
|
+
];
|
|
3330
|
+
}
|
|
3331
|
+
if (this.variant === 'interactive') {
|
|
3332
|
+
return [
|
|
3333
|
+
'text-foreground',
|
|
3334
|
+
'[&_thead]:sticky', '[&_thead]:top-0', '[&_thead]:z-10', '[&_thead]:bg-muted/70',
|
|
3335
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3336
|
+
'[&_th]:h-12', '[&_th]:px-4', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:text-sm', '[&_th]:font-medium',
|
|
3337
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3338
|
+
'[&_tbody_tr]:transition-colors', '[&_tbody_tr:hover]:bg-muted/50',
|
|
3339
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3340
|
+
'[&_td]:h-14', '[&_td]:px-4', '[&_td]:align-middle', '[&_td]:text-sm',
|
|
3341
|
+
'[&_svg]:text-muted-foreground'
|
|
3342
|
+
];
|
|
3343
|
+
}
|
|
3344
|
+
return [];
|
|
3345
|
+
}
|
|
3346
|
+
getCellClasses() {
|
|
3347
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
3348
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
3349
|
+
}
|
|
3350
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
3351
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
3352
|
+
}
|
|
3353
|
+
return [];
|
|
3354
|
+
}
|
|
3355
|
+
ngOnChanges(changes) {
|
|
3356
|
+
if (changes['reorderRows'] || changes['variant']) {
|
|
3357
|
+
this.syncReorderBehavior();
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
ngOnDestroy() {
|
|
3361
|
+
this.cleanupReorderBehavior();
|
|
3362
|
+
}
|
|
3363
|
+
syncReorderBehavior() {
|
|
3364
|
+
this.cleanupReorderBehavior();
|
|
3365
|
+
if (!this.reorderRows) {
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
const tbody = this.getTbody();
|
|
3369
|
+
if (!tbody) {
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
this.setRowsDraggable(tbody, true);
|
|
3373
|
+
this.cleanupListeners.push(this.renderer.listen(tbody, 'mousedown', (event) => this.armDragFromHandle(event)), this.renderer.listen(tbody, 'dragstart', (event) => this.onDragStart(event)), this.renderer.listen(tbody, 'dragover', (event) => this.onDragOver(event, tbody)), this.renderer.listen(tbody, 'drop', (event) => this.onDrop(event)), this.renderer.listen(tbody, 'dragend', () => this.onDragEnd()));
|
|
3374
|
+
// Observer para detectar cambios en el DOM (filas agregadas/removidas)
|
|
3375
|
+
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
3376
|
+
this.observer.observe(tbody, { childList: true });
|
|
3377
|
+
}
|
|
3378
|
+
cleanupReorderBehavior() {
|
|
3379
|
+
this.cleanupListeners.forEach((dispose) => dispose());
|
|
3380
|
+
this.cleanupListeners = [];
|
|
3381
|
+
if (this.observer) {
|
|
3382
|
+
this.observer.disconnect();
|
|
3383
|
+
this.observer = undefined;
|
|
3384
|
+
}
|
|
3385
|
+
const tbody = this.getTbody();
|
|
3386
|
+
if (tbody) {
|
|
3387
|
+
this.setRowsDraggable(tbody, false);
|
|
3388
|
+
}
|
|
3389
|
+
this.draggedRow = null;
|
|
3390
|
+
}
|
|
3391
|
+
getTbody() {
|
|
3392
|
+
return this.tableElement?.nativeElement.tBodies.item(0) ?? null;
|
|
3393
|
+
}
|
|
3394
|
+
setRowsDraggable(tbody, enabled) {
|
|
3395
|
+
const rows = Array.from(tbody.rows);
|
|
3396
|
+
rows.forEach((row) => {
|
|
3397
|
+
this.syncAutoDragHandle(row, enabled);
|
|
3398
|
+
row.draggable = false;
|
|
3399
|
+
if (!enabled) {
|
|
3400
|
+
delete row.dataset['dragging'];
|
|
3401
|
+
delete row.dataset['dragArmed'];
|
|
3402
|
+
}
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
/**
|
|
3406
|
+
* Inserta un handle de drag automático si no existe uno custom
|
|
3407
|
+
*/
|
|
3408
|
+
syncAutoDragHandle(row, enabled) {
|
|
3409
|
+
const firstCell = row.cells.item(0);
|
|
3410
|
+
if (!firstCell) {
|
|
3411
|
+
return;
|
|
3412
|
+
}
|
|
3413
|
+
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
3414
|
+
if (!enabled) {
|
|
3415
|
+
existingAutoHandle?.remove();
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
3419
|
+
if (hasCustomHandle || existingAutoHandle) {
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
// Crear handle automático
|
|
3423
|
+
const button = this.renderer.createElement('button');
|
|
3424
|
+
this.renderer.setAttribute(button, 'type', 'button');
|
|
3425
|
+
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
3426
|
+
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
3427
|
+
this.renderer.addClass(button, 'inline-flex');
|
|
3428
|
+
this.renderer.addClass(button, 'h-7');
|
|
3429
|
+
this.renderer.addClass(button, 'w-7');
|
|
3430
|
+
this.renderer.addClass(button, 'items-center');
|
|
3431
|
+
this.renderer.addClass(button, 'justify-center');
|
|
3432
|
+
this.renderer.addClass(button, 'cursor-grab');
|
|
3433
|
+
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
3434
|
+
this.renderer.addClass(button, 'text-muted-foreground');
|
|
3435
|
+
const dots = this.renderer.createElement('span');
|
|
3436
|
+
this.renderer.addClass(dots, 'text-sm');
|
|
3437
|
+
this.renderer.addClass(dots, 'leading-none');
|
|
3438
|
+
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
3439
|
+
this.renderer.appendChild(button, dots);
|
|
3440
|
+
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
3441
|
+
}
|
|
3442
|
+
onDragStart(event) {
|
|
3443
|
+
const target = event.target;
|
|
3444
|
+
const row = target?.closest('tr');
|
|
3445
|
+
if (!row) {
|
|
3446
|
+
return;
|
|
3447
|
+
}
|
|
3448
|
+
const handle = target?.closest(this.dragHandleSelector);
|
|
3449
|
+
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
3450
|
+
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
3451
|
+
event.preventDefault();
|
|
3452
|
+
return;
|
|
3453
|
+
}
|
|
3454
|
+
this.draggedRow = row;
|
|
3455
|
+
this.draggedRow.dataset['dragging'] = 'true';
|
|
3456
|
+
if (event.dataTransfer) {
|
|
3457
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
3458
|
+
event.dataTransfer.setData('text/plain', '');
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
onDragOver(event, tbody) {
|
|
3462
|
+
if (!this.draggedRow) {
|
|
3463
|
+
return;
|
|
3464
|
+
}
|
|
3465
|
+
event.preventDefault();
|
|
3466
|
+
const target = event.target;
|
|
3467
|
+
const targetRow = target?.closest('tr');
|
|
3468
|
+
if (!targetRow || targetRow === this.draggedRow) {
|
|
3469
|
+
return;
|
|
3470
|
+
}
|
|
3471
|
+
const rect = targetRow.getBoundingClientRect();
|
|
3472
|
+
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
3473
|
+
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
3474
|
+
}
|
|
3475
|
+
onDrop(event) {
|
|
3476
|
+
event.preventDefault();
|
|
3477
|
+
}
|
|
3478
|
+
onDragEnd() {
|
|
3479
|
+
const tbody = this.getTbody();
|
|
3480
|
+
if (tbody) {
|
|
3481
|
+
Array.from(tbody.rows).forEach((row) => {
|
|
3482
|
+
row.draggable = false;
|
|
3483
|
+
delete row.dataset['dragArmed'];
|
|
3484
|
+
});
|
|
3485
|
+
}
|
|
3486
|
+
if (this.draggedRow) {
|
|
3487
|
+
delete this.draggedRow.dataset['dragging'];
|
|
3488
|
+
this.draggedRow = null;
|
|
3489
|
+
}
|
|
3490
|
+
if (!tbody) {
|
|
3491
|
+
return;
|
|
3492
|
+
}
|
|
3493
|
+
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
3494
|
+
this.rowOrderChange.emit(order);
|
|
3495
|
+
}
|
|
3496
|
+
armDragFromHandle(event) {
|
|
3497
|
+
const target = event.target;
|
|
3498
|
+
const handle = target?.closest(this.dragHandleSelector);
|
|
3499
|
+
if (!handle) {
|
|
3500
|
+
return;
|
|
3501
|
+
}
|
|
3502
|
+
const row = handle.closest('tr');
|
|
3503
|
+
if (!row) {
|
|
3504
|
+
return;
|
|
3505
|
+
}
|
|
3506
|
+
row.draggable = true;
|
|
3507
|
+
row.dataset['dragArmed'] = 'true';
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
PdmDraggableTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
3511
|
+
PdmDraggableTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDraggableTableComponent, selector: "pdm-draggable-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed", reorderRows: "reorderRows", dragHandleSelector: "dragHandleSelector" }, outputs: { rowOrderChange: "rowOrderChange" }, viewQueries: [{ propertyName: "tableElement", first: true, predicate: ["tableElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, decorators: [{
|
|
3513
|
+
type: Component,
|
|
3514
|
+
args: [{ selector: 'pdm-draggable-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
|
|
3515
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
3516
|
+
type: Input
|
|
3517
|
+
}], responsiveStrategy: [{
|
|
3518
|
+
type: Input
|
|
3519
|
+
}], className: [{
|
|
3520
|
+
type: Input
|
|
3521
|
+
}], fullBleed: [{
|
|
3522
|
+
type: Input
|
|
3523
|
+
}], reorderRows: [{
|
|
3524
|
+
type: Input
|
|
3525
|
+
}], dragHandleSelector: [{
|
|
3526
|
+
type: Input
|
|
3527
|
+
}], rowOrderChange: [{
|
|
3528
|
+
type: Output
|
|
3529
|
+
}], tableElement: [{
|
|
3530
|
+
type: ViewChild,
|
|
3531
|
+
args: ['tableElement']
|
|
3532
|
+
}] } });
|
|
3533
|
+
|
|
2505
3534
|
class PdmDropdownMenuComponent {
|
|
2506
3535
|
constructor(elementRef, cdr, overlay, viewContainerRef) {
|
|
2507
3536
|
this.elementRef = elementRef;
|
|
@@ -2616,7 +3645,7 @@ class PdmDropdownMenuComponent {
|
|
|
2616
3645
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 8);
|
|
2617
3646
|
// Resolve panelClass: overlayOptions.panelClass wins; otherwise map panelClassName.
|
|
2618
3647
|
const resolvedPanelClass = this.overlayOptions?.panelClass
|
|
2619
|
-
?? (this.panelClassName ? [
|
|
3648
|
+
?? (this.panelClassName ? [Z_INDEX.popover, this.panelClassName] : [Z_INDEX.popover]);
|
|
2620
3649
|
this.overlayRef = this.overlay.create({
|
|
2621
3650
|
positionStrategy,
|
|
2622
3651
|
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
@@ -2687,13 +3716,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2687
3716
|
args: ['document:keydown.escape']
|
|
2688
3717
|
}] } });
|
|
2689
3718
|
|
|
3719
|
+
/**
|
|
3720
|
+
* Drawer/Sheet component con soporte responsive
|
|
3721
|
+
*
|
|
3722
|
+
* MEJORADO en v0.2.0:
|
|
3723
|
+
* - Posicionamiento configurable (bottom, left, right, top)
|
|
3724
|
+
* - Tamaños predefinidos
|
|
3725
|
+
* - Responsive: bottom sheet en mobile, side panel en desktop
|
|
3726
|
+
* - Contenido genérico via ng-content
|
|
3727
|
+
*
|
|
3728
|
+
* @example
|
|
3729
|
+
* // Drawer simple desde el bottom
|
|
3730
|
+
* <pdm-drawer [open]="isOpen" position="bottom">
|
|
3731
|
+
* <h3>Title</h3>
|
|
3732
|
+
* <p>Content</p>
|
|
3733
|
+
* </pdm-drawer>
|
|
3734
|
+
*
|
|
3735
|
+
* @example
|
|
3736
|
+
* // Side panel desde la right
|
|
3737
|
+
* <pdm-drawer [open]="isOpen" position="right" size="md">
|
|
3738
|
+
* <p>Content</p>
|
|
3739
|
+
* </pdm-drawer>
|
|
3740
|
+
*/
|
|
2690
3741
|
class PdmDrawerComponent {
|
|
2691
3742
|
constructor() {
|
|
2692
3743
|
this.open = false;
|
|
3744
|
+
/**
|
|
3745
|
+
* Posición del drawer
|
|
3746
|
+
* - bottom: desde abajo (default, mejor para mobile)
|
|
3747
|
+
* - left: side panel desde izquierda
|
|
3748
|
+
* - right: side panel desde derecha
|
|
3749
|
+
* - top: desde arriba (poco común)
|
|
3750
|
+
*/
|
|
3751
|
+
this.position = 'bottom';
|
|
3752
|
+
/**
|
|
3753
|
+
* Tamaño del drawer
|
|
3754
|
+
* - sm: 400px (side) / 50vh (bottom/top)
|
|
3755
|
+
* - md: 500px (side) / 66vh (bottom/top) (default)
|
|
3756
|
+
* - lg: 640px (side) / 80vh (bottom/top)
|
|
3757
|
+
* - full: 100% ancho/alto
|
|
3758
|
+
*/
|
|
3759
|
+
this.size = 'md';
|
|
3760
|
+
/**
|
|
3761
|
+
* @deprecated Use position="bottom" instead
|
|
3762
|
+
*/
|
|
2693
3763
|
this.variant = 'drawer';
|
|
2694
3764
|
this.className = '';
|
|
2695
3765
|
this.title = '';
|
|
2696
3766
|
this.description = '';
|
|
3767
|
+
/**
|
|
3768
|
+
* Mostrar handle visual (línea para arrastrar)
|
|
3769
|
+
* Solo tiene sentido en position="bottom"
|
|
3770
|
+
*/
|
|
3771
|
+
this.showHandle = true;
|
|
3772
|
+
/**
|
|
3773
|
+
* Mostrar botón de cerrar
|
|
3774
|
+
*/
|
|
3775
|
+
this.showCloseButton = true;
|
|
3776
|
+
this.closeOnEsc = true;
|
|
3777
|
+
this.closeOnBackdropClick = true;
|
|
3778
|
+
this.openChange = new EventEmitter();
|
|
3779
|
+
// DEPRECATED: contenido específico que se movió a ng-content
|
|
2697
3780
|
this.value = '';
|
|
2698
3781
|
this.unit = '';
|
|
2699
3782
|
this.decrementLabel = '-';
|
|
@@ -2707,14 +3790,9 @@ class PdmDrawerComponent {
|
|
|
2707
3790
|
this.usernameLabel = 'Username';
|
|
2708
3791
|
this.usernameValue = '';
|
|
2709
3792
|
this.responsivePrimaryLabel = '';
|
|
2710
|
-
|
|
2711
|
-
this.closeOnEsc = true;
|
|
2712
|
-
/** Close when the backdrop is clicked. Default: `true`. */
|
|
2713
|
-
this.closeOnBackdropClick = true;
|
|
2714
|
-
this.openChange = new EventEmitter();
|
|
3793
|
+
this.bars = [];
|
|
2715
3794
|
this.primaryAction = new EventEmitter();
|
|
2716
3795
|
this.secondaryAction = new EventEmitter();
|
|
2717
|
-
this.bars = [];
|
|
2718
3796
|
}
|
|
2719
3797
|
onEsc() {
|
|
2720
3798
|
if (this.open && this.closeOnEsc) {
|
|
@@ -2735,14 +3813,67 @@ class PdmDrawerComponent {
|
|
|
2735
3813
|
onSecondaryAction() {
|
|
2736
3814
|
this.secondaryAction.emit();
|
|
2737
3815
|
}
|
|
3816
|
+
get containerClassName() {
|
|
3817
|
+
return `fixed inset-0 ${Z_INDEX.drawer} ${this.className}`;
|
|
3818
|
+
}
|
|
3819
|
+
get panelClassName() {
|
|
3820
|
+
const base = [
|
|
3821
|
+
'absolute',
|
|
3822
|
+
'bg-background',
|
|
3823
|
+
'border',
|
|
3824
|
+
'border-border',
|
|
3825
|
+
'shadow-lg',
|
|
3826
|
+
'overflow-auto'
|
|
3827
|
+
];
|
|
3828
|
+
// Posicionamiento
|
|
3829
|
+
const positionClasses = this.getPositionClasses();
|
|
3830
|
+
// Tamaño
|
|
3831
|
+
const sizeClasses = this.getSizeClasses();
|
|
3832
|
+
return [...base, ...positionClasses, ...sizeClasses].filter(Boolean).join(' ');
|
|
3833
|
+
}
|
|
3834
|
+
getPositionClasses() {
|
|
3835
|
+
const map = {
|
|
3836
|
+
bottom: ['inset-x-0', 'bottom-0', 'rounded-t-xl'],
|
|
3837
|
+
top: ['inset-x-0', 'top-0', 'rounded-b-xl'],
|
|
3838
|
+
left: ['inset-y-0', 'left-0', 'rounded-r-xl'],
|
|
3839
|
+
right: ['inset-y-0', 'right-0', 'rounded-l-xl']
|
|
3840
|
+
};
|
|
3841
|
+
return map[this.position] || map.bottom;
|
|
3842
|
+
}
|
|
3843
|
+
getSizeClasses() {
|
|
3844
|
+
const isVertical = this.position === 'bottom' || this.position === 'top';
|
|
3845
|
+
if (this.size === 'full') {
|
|
3846
|
+
return ['w-full', 'h-full'];
|
|
3847
|
+
}
|
|
3848
|
+
const sizeMap = {
|
|
3849
|
+
sm: isVertical ? 'max-h-[50vh]' : 'max-w-[400px]',
|
|
3850
|
+
md: isVertical ? 'max-h-[66vh]' : 'max-w-[500px]',
|
|
3851
|
+
lg: isVertical ? 'max-h-[80vh]' : 'max-w-[640px]'
|
|
3852
|
+
};
|
|
3853
|
+
const maxDimension = sizeMap[this.size] || sizeMap.md;
|
|
3854
|
+
if (isVertical) {
|
|
3855
|
+
return ['w-full', maxDimension];
|
|
3856
|
+
}
|
|
3857
|
+
else {
|
|
3858
|
+
return ['h-full', maxDimension];
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
get showLegacyContent() {
|
|
3862
|
+
// Mostrar contenido legacy si variant está siendo usado
|
|
3863
|
+
return this.variant === 'drawer' || this.variant === 'responsive-dialog';
|
|
3864
|
+
}
|
|
2738
3865
|
}
|
|
2739
3866
|
PdmDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2740
|
-
PdmDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDrawerComponent, selector: "pdm-drawer", inputs: { open: "open", variant: "variant", className: "className", title: "title", description: "description", value: "value", unit: "unit", decrementLabel: "decrementLabel", incrementLabel: "incrementLabel", primaryLabel: "primaryLabel", secondaryLabel: "secondaryLabel", profileTitle: "profileTitle", profileDescription: "profileDescription", nameLabel: "nameLabel", nameValue: "nameValue", usernameLabel: "usernameLabel", usernameValue: "usernameValue", responsivePrimaryLabel: "responsivePrimaryLabel",
|
|
3867
|
+
PdmDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDrawerComponent, selector: "pdm-drawer", inputs: { open: "open", position: "position", size: "size", variant: "variant", className: "className", title: "title", description: "description", showHandle: "showHandle", showCloseButton: "showCloseButton", closeOnEsc: "closeOnEsc", closeOnBackdropClick: "closeOnBackdropClick", value: "value", unit: "unit", decrementLabel: "decrementLabel", incrementLabel: "incrementLabel", primaryLabel: "primaryLabel", secondaryLabel: "secondaryLabel", profileTitle: "profileTitle", profileDescription: "profileDescription", nameLabel: "nameLabel", nameValue: "nameValue", usernameLabel: "usernameLabel", usernameValue: "usernameValue", responsivePrimaryLabel: "responsivePrimaryLabel", bars: "bars" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Panel -->\n <section [ngClass]=\"panelClassName\">\n <!-- Handle visual (solo para bottom) -->\n <div \n *ngIf=\"showHandle && position === 'bottom'\" \n class=\"mx-auto mb-4 mt-2 h-1 w-10 rounded-full bg-border\">\n </div>\n\n <!-- Header (opcional) -->\n <div *ngIf=\"title || description || showCloseButton\" class=\"flex items-start justify-between gap-4 p-6 pb-4\">\n <div *ngIf=\"title || description\" class=\"flex-1 min-w-0\">\n <h3 *ngIf=\"title\" class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">\n {{ title }}\n </h3>\n <p *ngIf=\"description\" class=\"m-0 mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </p>\n </div>\n \n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n (click)=\"close()\"\n aria-label=\"Close drawer\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"px-6 pb-6\">\n <!-- Contenido gen\u00E9rico -->\n <ng-container *ngIf=\"!showLegacyContent\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- LEGACY: contenido espec\u00EDfico hardcodeado (backward compatibility) -->\n <ng-container *ngIf=\"showLegacyContent\">\n <!-- Variant: drawer -->\n <div *ngIf=\"variant === 'drawer'\" class=\"mx-auto flex max-w-sm flex-col items-center\">\n <div *ngIf=\"value !== ''\" class=\"mt-3 flex w-full items-center justify-center gap-4\">\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ decrementLabel }}</button>\n <div class=\"text-center\">\n <div class=\"text-5xl font-semibold leading-none text-foreground\">{{ value }}</div>\n <div *ngIf=\"unit\" class=\"mt-1 text-xs tracking-wide text-muted-foreground\">{{ unit }}</div>\n </div>\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ incrementLabel }}</button>\n </div>\n\n <div *ngIf=\"bars.length\" class=\"mt-3 flex h-14 w-full items-end gap-1\">\n <div *ngFor=\"let bar of bars\" class=\"flex-1 bg-foreground\" [style.height.px]=\"bar\"></div>\n </div>\n\n <button *ngIf=\"primaryLabel\" type=\"button\" class=\"mt-3 h-9 w-full appearance-none rounded-md bg-primary text-sm font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ primaryLabel }}</button>\n <button *ngIf=\"secondaryLabel\" type=\"button\" class=\"mt-2 h-9 w-full appearance-none rounded-md border border-input bg-background text-sm font-medium text-foreground\" (click)=\"onSecondaryAction()\">{{ secondaryLabel }}</button>\n </div>\n\n <!-- Variant: responsive-dialog -->\n <div *ngIf=\"variant === 'responsive-dialog'\" class=\"flex flex-col gap-3\">\n <div *ngIf=\"nameLabel && nameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ nameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ nameValue }}</div>\n </div>\n <div *ngIf=\"usernameLabel && usernameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ usernameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ usernameValue }}</div>\n </div>\n\n <button *ngIf=\"responsivePrimaryLabel\" type=\"button\" class=\"mt-3 h-8 w-full appearance-none rounded-md bg-primary text-xs font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ responsivePrimaryLabel }}</button>\n </div>\n </ng-container>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2741
3868
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, decorators: [{
|
|
2742
3869
|
type: Component,
|
|
2743
|
-
args: [{ selector: 'pdm-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3870
|
+
args: [{ selector: 'pdm-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Panel -->\n <section [ngClass]=\"panelClassName\">\n <!-- Handle visual (solo para bottom) -->\n <div \n *ngIf=\"showHandle && position === 'bottom'\" \n class=\"mx-auto mb-4 mt-2 h-1 w-10 rounded-full bg-border\">\n </div>\n\n <!-- Header (opcional) -->\n <div *ngIf=\"title || description || showCloseButton\" class=\"flex items-start justify-between gap-4 p-6 pb-4\">\n <div *ngIf=\"title || description\" class=\"flex-1 min-w-0\">\n <h3 *ngIf=\"title\" class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">\n {{ title }}\n </h3>\n <p *ngIf=\"description\" class=\"m-0 mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </p>\n </div>\n \n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n (click)=\"close()\"\n aria-label=\"Close drawer\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"px-6 pb-6\">\n <!-- Contenido gen\u00E9rico -->\n <ng-container *ngIf=\"!showLegacyContent\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- LEGACY: contenido espec\u00EDfico hardcodeado (backward compatibility) -->\n <ng-container *ngIf=\"showLegacyContent\">\n <!-- Variant: drawer -->\n <div *ngIf=\"variant === 'drawer'\" class=\"mx-auto flex max-w-sm flex-col items-center\">\n <div *ngIf=\"value !== ''\" class=\"mt-3 flex w-full items-center justify-center gap-4\">\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ decrementLabel }}</button>\n <div class=\"text-center\">\n <div class=\"text-5xl font-semibold leading-none text-foreground\">{{ value }}</div>\n <div *ngIf=\"unit\" class=\"mt-1 text-xs tracking-wide text-muted-foreground\">{{ unit }}</div>\n </div>\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ incrementLabel }}</button>\n </div>\n\n <div *ngIf=\"bars.length\" class=\"mt-3 flex h-14 w-full items-end gap-1\">\n <div *ngFor=\"let bar of bars\" class=\"flex-1 bg-foreground\" [style.height.px]=\"bar\"></div>\n </div>\n\n <button *ngIf=\"primaryLabel\" type=\"button\" class=\"mt-3 h-9 w-full appearance-none rounded-md bg-primary text-sm font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ primaryLabel }}</button>\n <button *ngIf=\"secondaryLabel\" type=\"button\" class=\"mt-2 h-9 w-full appearance-none rounded-md border border-input bg-background text-sm font-medium text-foreground\" (click)=\"onSecondaryAction()\">{{ secondaryLabel }}</button>\n </div>\n\n <!-- Variant: responsive-dialog -->\n <div *ngIf=\"variant === 'responsive-dialog'\" class=\"flex flex-col gap-3\">\n <div *ngIf=\"nameLabel && nameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ nameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ nameValue }}</div>\n </div>\n <div *ngIf=\"usernameLabel && usernameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ usernameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ usernameValue }}</div>\n </div>\n\n <button *ngIf=\"responsivePrimaryLabel\" type=\"button\" class=\"mt-3 h-8 w-full appearance-none rounded-md bg-primary text-xs font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ responsivePrimaryLabel }}</button>\n </div>\n </ng-container>\n </div>\n </section>\n</div>\n" }]
|
|
2744
3871
|
}], propDecorators: { open: [{
|
|
2745
3872
|
type: Input
|
|
3873
|
+
}], position: [{
|
|
3874
|
+
type: Input
|
|
3875
|
+
}], size: [{
|
|
3876
|
+
type: Input
|
|
2746
3877
|
}], variant: [{
|
|
2747
3878
|
type: Input
|
|
2748
3879
|
}], className: [{
|
|
@@ -2751,6 +3882,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2751
3882
|
type: Input
|
|
2752
3883
|
}], description: [{
|
|
2753
3884
|
type: Input
|
|
3885
|
+
}], showHandle: [{
|
|
3886
|
+
type: Input
|
|
3887
|
+
}], showCloseButton: [{
|
|
3888
|
+
type: Input
|
|
3889
|
+
}], closeOnEsc: [{
|
|
3890
|
+
type: Input
|
|
3891
|
+
}], closeOnBackdropClick: [{
|
|
3892
|
+
type: Input
|
|
3893
|
+
}], openChange: [{
|
|
3894
|
+
type: Output
|
|
2754
3895
|
}], value: [{
|
|
2755
3896
|
type: Input
|
|
2756
3897
|
}], unit: [{
|
|
@@ -2777,18 +3918,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2777
3918
|
type: Input
|
|
2778
3919
|
}], responsivePrimaryLabel: [{
|
|
2779
3920
|
type: Input
|
|
2780
|
-
}],
|
|
2781
|
-
type: Input
|
|
2782
|
-
}], closeOnBackdropClick: [{
|
|
3921
|
+
}], bars: [{
|
|
2783
3922
|
type: Input
|
|
2784
|
-
}], openChange: [{
|
|
2785
|
-
type: Output
|
|
2786
3923
|
}], primaryAction: [{
|
|
2787
3924
|
type: Output
|
|
2788
3925
|
}], secondaryAction: [{
|
|
2789
3926
|
type: Output
|
|
2790
|
-
}], bars: [{
|
|
2791
|
-
type: Input
|
|
2792
3927
|
}], onEsc: [{
|
|
2793
3928
|
type: HostListener,
|
|
2794
3929
|
args: ['document:keydown.escape']
|
|
@@ -2933,10 +4068,10 @@ class PdmHoverCardComponent {
|
|
|
2933
4068
|
}
|
|
2934
4069
|
}
|
|
2935
4070
|
PdmHoverCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2936
|
-
PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-
|
|
4071
|
+
PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2937
4072
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, decorators: [{
|
|
2938
4073
|
type: Component,
|
|
2939
|
-
args: [{ selector: 'pdm-hover-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-
|
|
4074
|
+
args: [{ selector: 'pdm-hover-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n</div>\n" }]
|
|
2940
4075
|
}], propDecorators: { className: [{
|
|
2941
4076
|
type: Input
|
|
2942
4077
|
}], panelClassName: [{
|
|
@@ -3372,10 +4507,10 @@ class PdmMenubarComponent {
|
|
|
3372
4507
|
}
|
|
3373
4508
|
}
|
|
3374
4509
|
PdmMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3375
|
-
PdmMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmMenubarComponent, selector: "pdm-menubar", inputs: { menus: "menus", className: "className" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-
|
|
4510
|
+
PdmMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmMenubarComponent, selector: "pdm-menubar", inputs: { menus: "menus", className: "className" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3376
4511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, decorators: [{
|
|
3377
4512
|
type: Component,
|
|
3378
|
-
args: [{ selector: 'pdm-menubar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-
|
|
4513
|
+
args: [{ selector: 'pdm-menubar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\n" }]
|
|
3379
4514
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
|
|
3380
4515
|
type: Input
|
|
3381
4516
|
}], className: [{
|
|
@@ -3425,21 +4560,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3425
4560
|
type: Output
|
|
3426
4561
|
}] } });
|
|
3427
4562
|
|
|
4563
|
+
/**
|
|
4564
|
+
* Navigation Menu component - Navegación horizontal responsive
|
|
4565
|
+
*
|
|
4566
|
+
* MEJORAS en v0.2.0:
|
|
4567
|
+
* - Modo scroll: overflow-x-auto con scroll indicators en mobile
|
|
4568
|
+
* - Modo compact: items abreviados en mobile, completos en desktop
|
|
4569
|
+
* - Scroll smooth automático al item activo
|
|
4570
|
+
*
|
|
4571
|
+
* @example
|
|
4572
|
+
* <!-- Scroll horizontal (default) -->
|
|
4573
|
+
* <pdm-navigation-menu [items]="navItems"></pdm-navigation-menu>
|
|
4574
|
+
*
|
|
4575
|
+
* <!-- Compact mode -->
|
|
4576
|
+
* <pdm-navigation-menu [items]="navItems" mobileMode="compact"></pdm-navigation-menu>
|
|
4577
|
+
*/
|
|
3428
4578
|
class PdmNavigationMenuComponent {
|
|
3429
4579
|
constructor() {
|
|
3430
4580
|
this.items = [];
|
|
3431
4581
|
this.className = '';
|
|
4582
|
+
/**
|
|
4583
|
+
* Mobile behavior: 'scroll' (horizontal scroll) o 'compact' (items reducidos)
|
|
4584
|
+
* @default 'scroll'
|
|
4585
|
+
*/
|
|
4586
|
+
this.mobileMode = 'scroll';
|
|
3432
4587
|
}
|
|
3433
4588
|
}
|
|
3434
4589
|
PdmNavigationMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3435
|
-
PdmNavigationMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmNavigationMenuComponent, selector: "pdm-navigation-menu", inputs: { items: "items", className: "className" }, ngImport: i0, template: "<nav
|
|
4590
|
+
PdmNavigationMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmNavigationMenuComponent, selector: "pdm-navigation-menu", inputs: { items: "items", className: "className", mobileMode: "mobileMode" }, ngImport: i0, template: "<nav\n [ngClass]=\"[\n 'relative z-10 flex w-full items-center',\n mobileMode === 'scroll' ? 'overflow-x-auto scrollbar-thin' : '',\n className\n ]\"\n>\n <ul\n [ngClass]=\"[\n 'group flex list-none items-center gap-1',\n mobileMode === 'scroll' ? 'flex-nowrap' : 'flex-wrap justify-center'\n ]\"\n >\n <li *ngFor=\"let item of items\">\n <a\n [href]=\"item.href || '#'\"\n [ngClass]=\"[\n 'group inline-flex h-9 items-center justify-center rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 whitespace-nowrap',\n item.active ? 'bg-accent text-accent-foreground' : 'text-foreground'\n ]\"\n >\n {{ item.label }}\n </a>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3436
4591
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, decorators: [{
|
|
3437
4592
|
type: Component,
|
|
3438
|
-
args: [{ selector: 'pdm-navigation-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav
|
|
4593
|
+
args: [{ selector: 'pdm-navigation-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n [ngClass]=\"[\n 'relative z-10 flex w-full items-center',\n mobileMode === 'scroll' ? 'overflow-x-auto scrollbar-thin' : '',\n className\n ]\"\n>\n <ul\n [ngClass]=\"[\n 'group flex list-none items-center gap-1',\n mobileMode === 'scroll' ? 'flex-nowrap' : 'flex-wrap justify-center'\n ]\"\n >\n <li *ngFor=\"let item of items\">\n <a\n [href]=\"item.href || '#'\"\n [ngClass]=\"[\n 'group inline-flex h-9 items-center justify-center rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 whitespace-nowrap',\n item.active ? 'bg-accent text-accent-foreground' : 'text-foreground'\n ]\"\n >\n {{ item.label }}\n </a>\n </li>\n </ul>\n</nav>\n" }]
|
|
3439
4594
|
}], propDecorators: { items: [{
|
|
3440
4595
|
type: Input
|
|
3441
4596
|
}], className: [{
|
|
3442
4597
|
type: Input
|
|
4598
|
+
}], mobileMode: [{
|
|
4599
|
+
type: Input
|
|
3443
4600
|
}] } });
|
|
3444
4601
|
|
|
3445
4602
|
/**
|
|
@@ -3657,8 +4814,9 @@ class PdmSelectComponent {
|
|
|
3657
4814
|
this.cdr.markForCheck();
|
|
3658
4815
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 4);
|
|
3659
4816
|
this.overlayRef = this.overlay.create({
|
|
3660
|
-
//
|
|
3661
|
-
panelClass
|
|
4817
|
+
// CRÍTICO: z-[70] para aparecer SOBRE modals (z-[60])
|
|
4818
|
+
// panelClass se aplica al cdk-overlay-pane wrapper
|
|
4819
|
+
panelClass: [Z_INDEX.popover],
|
|
3662
4820
|
positionStrategy,
|
|
3663
4821
|
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
3664
4822
|
width: triggerEl.offsetWidth,
|
|
@@ -3773,10 +4931,10 @@ class PdmPaginationComponent {
|
|
|
3773
4931
|
}
|
|
3774
4932
|
}
|
|
3775
4933
|
PdmPaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3776
|
-
PdmPaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPaginationComponent, selector: "pdm-pagination", inputs: { page: "page", pageCount: "pageCount", maxVisible: "maxVisible", className: "className", rowsPerPageLabel: "rowsPerPageLabel", rowsPerPage: "rowsPerPage", rowsPerPageOptions: "rowsPerPageOptions" }, outputs: { pageChange: "pageChange", rowsPerPageChange: "rowsPerPageChange" }, ngImport: i0, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }, { kind: "component", type: PdmSelectComponent, selector: "pdm-select", inputs: ["id", "value", "options", "disabled", "invalid", "className", "placeholder", "overlayOptions"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4934
|
+
PdmPaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPaginationComponent, selector: "pdm-pagination", inputs: { page: "page", pageCount: "pageCount", maxVisible: "maxVisible", className: "className", rowsPerPageLabel: "rowsPerPageLabel", rowsPerPage: "rowsPerPage", rowsPerPageOptions: "rowsPerPageOptions" }, outputs: { pageChange: "pageChange", rowsPerPageChange: "rowsPerPageChange" }, ngImport: i0, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[100px] sm:w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }, { kind: "component", type: PdmSelectComponent, selector: "pdm-select", inputs: ["id", "value", "options", "disabled", "invalid", "className", "placeholder", "overlayOptions"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3777
4935
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, decorators: [{
|
|
3778
4936
|
type: Component,
|
|
3779
|
-
args: [{ selector: 'pdm-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n" }]
|
|
4937
|
+
args: [{ selector: 'pdm-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[100px] sm:w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n" }]
|
|
3780
4938
|
}], propDecorators: { page: [{
|
|
3781
4939
|
type: Input
|
|
3782
4940
|
}], pageCount: [{
|
|
@@ -3832,10 +4990,11 @@ class PdmPopoverComponent {
|
|
|
3832
4990
|
return this._open;
|
|
3833
4991
|
}
|
|
3834
4992
|
get panelClasses() {
|
|
4993
|
+
const baseClasses = 'min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md';
|
|
3835
4994
|
return [
|
|
3836
4995
|
this.panelPlacement === 'top'
|
|
3837
|
-
?
|
|
3838
|
-
:
|
|
4996
|
+
? `absolute bottom-full left-0 ${Z_INDEX.popover} mb-2 ${baseClasses}`
|
|
4997
|
+
: `absolute left-0 top-full ${Z_INDEX.popover} mt-2 ${baseClasses}`,
|
|
3839
4998
|
this.panelClassName
|
|
3840
4999
|
];
|
|
3841
5000
|
}
|
|
@@ -4027,14 +5186,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4027
5186
|
type: Input
|
|
4028
5187
|
}] } });
|
|
4029
5188
|
|
|
5189
|
+
/**
|
|
5190
|
+
* Sheet/Side panel component con soporte responsive
|
|
5191
|
+
*
|
|
5192
|
+
* MEJORADO en v0.2.0:
|
|
5193
|
+
* - Tamaños configurables
|
|
5194
|
+
* - Mejor manejo de overflow
|
|
5195
|
+
* - Responsive sizes
|
|
5196
|
+
*
|
|
5197
|
+
* @example
|
|
5198
|
+
* <pdm-sheet [open]="isOpen" side="right" size="md">
|
|
5199
|
+
* <h3>Settings</h3>
|
|
5200
|
+
* <p>Content here</p>
|
|
5201
|
+
* </pdm-sheet>
|
|
5202
|
+
*/
|
|
4030
5203
|
class PdmSheetComponent {
|
|
4031
5204
|
constructor() {
|
|
4032
5205
|
this.open = false;
|
|
5206
|
+
/**
|
|
5207
|
+
* Lado desde donde aparece el sheet
|
|
5208
|
+
*/
|
|
4033
5209
|
this.side = 'right';
|
|
5210
|
+
/**
|
|
5211
|
+
* Tamaño del sheet
|
|
5212
|
+
* - sm: 320px (side) / 40vh (top/bottom)
|
|
5213
|
+
* - md: 400px (side) / 50vh (top/bottom) (default)
|
|
5214
|
+
* - lg: 500px (side) / 66vh (top/bottom)
|
|
5215
|
+
* - xl: 640px (side) / 80vh (top/bottom)
|
|
5216
|
+
* - full: 100%
|
|
5217
|
+
*/
|
|
5218
|
+
this.size = 'md';
|
|
4034
5219
|
this.className = '';
|
|
4035
|
-
/** Close when the ESC key is pressed. Default: `true`. */
|
|
4036
5220
|
this.closeOnEsc = true;
|
|
4037
|
-
/** Close when the backdrop is clicked. Default: `true`. */
|
|
4038
5221
|
this.closeOnBackdropClick = true;
|
|
4039
5222
|
this.openChange = new EventEmitter();
|
|
4040
5223
|
}
|
|
@@ -4052,24 +5235,56 @@ class PdmSheetComponent {
|
|
|
4052
5235
|
this.openChange.emit(false);
|
|
4053
5236
|
}
|
|
4054
5237
|
get panelClass() {
|
|
4055
|
-
|
|
4056
|
-
|
|
4057
|
-
|
|
4058
|
-
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
5238
|
+
const base = 'absolute bg-background border-border shadow-lg overflow-auto';
|
|
5239
|
+
const position = this.getPositionClass();
|
|
5240
|
+
const sizing = this.getSizingClass();
|
|
5241
|
+
return `${base} ${position} ${sizing} ${this.className}`.trim();
|
|
5242
|
+
}
|
|
5243
|
+
getPositionClass() {
|
|
5244
|
+
const map = {
|
|
5245
|
+
left: 'left-0 top-0 h-full border-r',
|
|
5246
|
+
right: 'right-0 top-0 h-full border-l',
|
|
5247
|
+
top: 'top-0 left-0 w-full border-b',
|
|
5248
|
+
bottom: 'bottom-0 left-0 w-full border-t'
|
|
5249
|
+
};
|
|
5250
|
+
return map[this.side];
|
|
5251
|
+
}
|
|
5252
|
+
getSizingClass() {
|
|
5253
|
+
if (this.size === 'full') {
|
|
5254
|
+
return 'w-full h-full';
|
|
5255
|
+
}
|
|
5256
|
+
const isHorizontal = this.side === 'left' || this.side === 'right';
|
|
5257
|
+
if (isHorizontal) {
|
|
5258
|
+
const widthMap = {
|
|
5259
|
+
sm: 'w-full max-w-[320px] sm:max-w-[320px]',
|
|
5260
|
+
md: 'w-full max-w-[360px] sm:max-w-[400px]',
|
|
5261
|
+
lg: 'w-full max-w-[400px] sm:max-w-[500px]',
|
|
5262
|
+
xl: 'w-full max-w-[500px] sm:max-w-[640px]'
|
|
5263
|
+
};
|
|
5264
|
+
return widthMap[this.size] || widthMap.md;
|
|
5265
|
+
}
|
|
5266
|
+
else {
|
|
5267
|
+
const heightMap = {
|
|
5268
|
+
sm: 'max-h-[40vh]',
|
|
5269
|
+
md: 'max-h-[50vh]',
|
|
5270
|
+
lg: 'max-h-[66vh]',
|
|
5271
|
+
xl: 'max-h-[80vh]'
|
|
5272
|
+
};
|
|
5273
|
+
return heightMap[this.size] || heightMap.md;
|
|
5274
|
+
}
|
|
4062
5275
|
}
|
|
4063
5276
|
}
|
|
4064
5277
|
PdmSheetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4065
|
-
PdmSheetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSheetComponent, selector: "pdm-sheet", inputs: { open: "open", side: "side", className: "className", closeOnEsc: "closeOnEsc", closeOnBackdropClick: "closeOnBackdropClick" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
5278
|
+
PdmSheetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSheetComponent, selector: "pdm-sheet", inputs: { open: "open", side: "side", size: "size", className: "className", closeOnEsc: "closeOnEsc", closeOnBackdropClick: "closeOnBackdropClick" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute z-[60] border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4066
5279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, decorators: [{
|
|
4067
5280
|
type: Component,
|
|
4068
|
-
args: [{ selector: 'pdm-sheet', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n" }]
|
|
5281
|
+
args: [{ selector: 'pdm-sheet', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute z-[60] border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n" }]
|
|
4069
5282
|
}], propDecorators: { open: [{
|
|
4070
5283
|
type: Input
|
|
4071
5284
|
}], side: [{
|
|
4072
5285
|
type: Input
|
|
5286
|
+
}], size: [{
|
|
5287
|
+
type: Input
|
|
4073
5288
|
}], className: [{
|
|
4074
5289
|
type: Input
|
|
4075
5290
|
}], closeOnEsc: [{
|
|
@@ -4083,21 +5298,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4083
5298
|
args: ['document:keydown.escape']
|
|
4084
5299
|
}] } });
|
|
4085
5300
|
|
|
5301
|
+
/**
|
|
5302
|
+
* Sidebar component - Navegación lateral responsive
|
|
5303
|
+
*
|
|
5304
|
+
* MEJORAS en v0.2.0:
|
|
5305
|
+
* - Mobile drawer mode: overlay fullscreen en mobile, sidebar fijo en desktop
|
|
5306
|
+
* - Sidebar mode: sidebar persistente con widths responsive
|
|
5307
|
+
* - Backdrop automático en mobile drawer mode
|
|
5308
|
+
*
|
|
5309
|
+
* @example
|
|
5310
|
+
* <!-- Mobile drawer (default) -->
|
|
5311
|
+
* <pdm-sidebar [open]="sidebarOpen" (openChange)="sidebarOpen = $event">
|
|
5312
|
+
* <nav>Menu items...</nav>
|
|
5313
|
+
* </pdm-sidebar>
|
|
5314
|
+
*
|
|
5315
|
+
* <!-- Sidebar persistente -->
|
|
5316
|
+
* <pdm-sidebar mobileMode="sidebar" [collapsed]="collapsed">
|
|
5317
|
+
* <nav>Menu items...</nav>
|
|
5318
|
+
* </pdm-sidebar>
|
|
5319
|
+
*/
|
|
4086
5320
|
class PdmSidebarComponent {
|
|
4087
5321
|
constructor() {
|
|
5322
|
+
/**
|
|
5323
|
+
* Mobile behavior: 'drawer' (overlay) o 'sidebar' (persistente)
|
|
5324
|
+
* @default 'drawer'
|
|
5325
|
+
*/
|
|
5326
|
+
this.mobileMode = 'drawer';
|
|
5327
|
+
/**
|
|
5328
|
+
* Collapsed state (solo aplica en mobileMode="sidebar")
|
|
5329
|
+
*/
|
|
4088
5330
|
this.collapsed = false;
|
|
5331
|
+
/**
|
|
5332
|
+
* Open state (solo aplica en mobileMode="drawer")
|
|
5333
|
+
*/
|
|
5334
|
+
this.open = false;
|
|
4089
5335
|
this.className = '';
|
|
5336
|
+
/**
|
|
5337
|
+
* Emite cuando el drawer se cierra (solo en mobileMode="drawer")
|
|
5338
|
+
*/
|
|
5339
|
+
this.openChange = new EventEmitter();
|
|
5340
|
+
}
|
|
5341
|
+
onBackdropClick() {
|
|
5342
|
+
if (this.mobileMode === 'drawer') {
|
|
5343
|
+
this.open = false;
|
|
5344
|
+
this.openChange.emit(false);
|
|
5345
|
+
}
|
|
4090
5346
|
}
|
|
4091
5347
|
}
|
|
4092
5348
|
PdmSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4093
|
-
PdmSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSidebarComponent, selector: "pdm-sidebar", inputs: { collapsed: "collapsed", className: "className" }, ngImport: i0, template: "<aside [ngClass]=\"['h-full border-r border-border bg-background transition-all'
|
|
5349
|
+
PdmSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSidebarComponent, selector: "pdm-sidebar", inputs: { mobileMode: "mobileMode", collapsed: "collapsed", open: "open", className: "className" }, outputs: { openChange: "openChange" }, ngImport: i0, template: "<!-- Mobile drawer mode -->\n<ng-container *ngIf=\"mobileMode === 'drawer'\">\n <!-- Backdrop -->\n <div\n *ngIf=\"open\"\n class=\"fixed inset-0 z-40 bg-black/50 lg:hidden\"\n (click)=\"onBackdropClick()\"\n ></div>\n \n <!-- Drawer -->\n <aside\n [ngClass]=\"[\n 'fixed inset-y-0 left-0 z-50 h-full w-64 transform border-r border-border bg-background transition-transform duration-300 lg:relative lg:z-auto lg:translate-x-0',\n open ? 'translate-x-0' : '-translate-x-full',\n className\n ]\"\n >\n <ng-content></ng-content>\n </aside>\n</ng-container>\n\n<!-- Sidebar persistente mode -->\n<aside\n *ngIf=\"mobileMode === 'sidebar'\"\n [ngClass]=\"[\n 'h-full border-r border-border bg-background transition-all',\n collapsed ? 'w-14 sm:w-14' : 'w-48 sm:w-56 lg:w-64',\n className\n ]\"\n>\n <ng-content></ng-content>\n</aside>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4094
5350
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, decorators: [{
|
|
4095
5351
|
type: Component,
|
|
4096
|
-
args: [{ selector: 'pdm-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<aside [ngClass]=\"['h-full border-r border-border bg-background transition-all'
|
|
4097
|
-
}], propDecorators: {
|
|
5352
|
+
args: [{ selector: 'pdm-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Mobile drawer mode -->\n<ng-container *ngIf=\"mobileMode === 'drawer'\">\n <!-- Backdrop -->\n <div\n *ngIf=\"open\"\n class=\"fixed inset-0 z-40 bg-black/50 lg:hidden\"\n (click)=\"onBackdropClick()\"\n ></div>\n \n <!-- Drawer -->\n <aside\n [ngClass]=\"[\n 'fixed inset-y-0 left-0 z-50 h-full w-64 transform border-r border-border bg-background transition-transform duration-300 lg:relative lg:z-auto lg:translate-x-0',\n open ? 'translate-x-0' : '-translate-x-full',\n className\n ]\"\n >\n <ng-content></ng-content>\n </aside>\n</ng-container>\n\n<!-- Sidebar persistente mode -->\n<aside\n *ngIf=\"mobileMode === 'sidebar'\"\n [ngClass]=\"[\n 'h-full border-r border-border bg-background transition-all',\n collapsed ? 'w-14 sm:w-14' : 'w-48 sm:w-56 lg:w-64',\n className\n ]\"\n>\n <ng-content></ng-content>\n</aside>\n" }]
|
|
5353
|
+
}], propDecorators: { mobileMode: [{
|
|
5354
|
+
type: Input
|
|
5355
|
+
}], collapsed: [{
|
|
5356
|
+
type: Input
|
|
5357
|
+
}], open: [{
|
|
4098
5358
|
type: Input
|
|
4099
5359
|
}], className: [{
|
|
4100
5360
|
type: Input
|
|
5361
|
+
}], openChange: [{
|
|
5362
|
+
type: Output
|
|
4101
5363
|
}] } });
|
|
4102
5364
|
|
|
4103
5365
|
class PdmSkeletonComponent {
|
|
@@ -4264,212 +5526,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4264
5526
|
type: Output
|
|
4265
5527
|
}] } });
|
|
4266
5528
|
|
|
4267
|
-
class PdmTableComponent {
|
|
4268
|
-
constructor(renderer) {
|
|
4269
|
-
this.renderer = renderer;
|
|
4270
|
-
this.variant = 'default';
|
|
4271
|
-
this.reorderRows = false;
|
|
4272
|
-
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
4273
|
-
this.className = '';
|
|
4274
|
-
this.rowOrderChange = new EventEmitter();
|
|
4275
|
-
this.cleanupListeners = [];
|
|
4276
|
-
this.draggedRow = null;
|
|
4277
|
-
}
|
|
4278
|
-
ngAfterViewInit() {
|
|
4279
|
-
this.syncReorderBehavior();
|
|
4280
|
-
}
|
|
4281
|
-
ngOnChanges(changes) {
|
|
4282
|
-
if (changes['reorderRows'] || changes['variant']) {
|
|
4283
|
-
this.syncReorderBehavior();
|
|
4284
|
-
}
|
|
4285
|
-
}
|
|
4286
|
-
ngOnDestroy() {
|
|
4287
|
-
this.cleanupReorderBehavior();
|
|
4288
|
-
}
|
|
4289
|
-
get wrapperClasses() {
|
|
4290
|
-
return [
|
|
4291
|
-
'relative w-full overflow-auto',
|
|
4292
|
-
this.variant === 'interactive' ? 'overflow-x-auto overflow-y-hidden rounded-xl border border-border bg-background' : '',
|
|
4293
|
-
this.variant === 'data' ? 'overflow-hidden rounded-md border border-border bg-background' : '',
|
|
4294
|
-
this.className
|
|
4295
|
-
];
|
|
4296
|
-
}
|
|
4297
|
-
get tableClasses() {
|
|
4298
|
-
return [
|
|
4299
|
-
'w-full caption-bottom text-sm',
|
|
4300
|
-
this.variant === 'data'
|
|
4301
|
-
? 'border-collapse text-foreground [&_thead_tr]:border-b [&_thead_tr]:border-border [&_tbody_tr]:border-b [&_tbody_tr]:border-border [&_tbody_tr:last-child]:border-b-0 [&_th]:h-10 [&_th]:px-2 [&_th]:text-left [&_th]:align-middle [&_th]:font-medium [&_td]:p-2 [&_td]:align-middle'
|
|
4302
|
-
: '',
|
|
4303
|
-
this.variant === 'interactive'
|
|
4304
|
-
? 'text-foreground [&_thead]:sticky [&_thead]:top-0 [&_thead]:z-10 [&_thead]:bg-muted/70 [&_thead_tr]:border-b [&_thead_tr]:border-border [&_th]:h-12 [&_th]:px-4 [&_th]:text-left [&_th]:align-middle [&_th]:text-sm [&_th]:font-medium [&_th]:whitespace-nowrap [&_tbody_tr]:border-b [&_tbody_tr]:border-border [&_tbody_tr]:transition-colors [&_tbody_tr:hover]:bg-muted/50 [&_tbody_tr:last-child]:border-b-0 [&_td]:h-14 [&_td]:px-4 [&_td]:align-middle [&_td]:text-sm [&_td]:whitespace-nowrap [&_td:first-child]:w-10 [&_td:last-child]:w-10 [&_svg]:text-muted-foreground'
|
|
4305
|
-
: ''
|
|
4306
|
-
];
|
|
4307
|
-
}
|
|
4308
|
-
syncReorderBehavior() {
|
|
4309
|
-
this.cleanupReorderBehavior();
|
|
4310
|
-
if (!this.isReorderEnabled) {
|
|
4311
|
-
return;
|
|
4312
|
-
}
|
|
4313
|
-
const tbody = this.getTbody();
|
|
4314
|
-
if (!tbody) {
|
|
4315
|
-
return;
|
|
4316
|
-
}
|
|
4317
|
-
this.setRowsDraggable(tbody, true);
|
|
4318
|
-
this.cleanupListeners.push(this.renderer.listen(tbody, 'mousedown', (event) => this.armDragFromHandle(event)), this.renderer.listen(tbody, 'dragstart', (event) => this.onDragStart(event)), this.renderer.listen(tbody, 'dragover', (event) => this.onDragOver(event, tbody)), this.renderer.listen(tbody, 'drop', (event) => this.onDrop(event)), this.renderer.listen(tbody, 'dragend', () => this.onDragEnd()));
|
|
4319
|
-
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
4320
|
-
this.observer.observe(tbody, { childList: true });
|
|
4321
|
-
}
|
|
4322
|
-
cleanupReorderBehavior() {
|
|
4323
|
-
this.cleanupListeners.forEach((dispose) => dispose());
|
|
4324
|
-
this.cleanupListeners = [];
|
|
4325
|
-
if (this.observer) {
|
|
4326
|
-
this.observer.disconnect();
|
|
4327
|
-
this.observer = undefined;
|
|
4328
|
-
}
|
|
4329
|
-
const tbody = this.getTbody();
|
|
4330
|
-
if (tbody) {
|
|
4331
|
-
this.setRowsDraggable(tbody, false);
|
|
4332
|
-
}
|
|
4333
|
-
this.draggedRow = null;
|
|
4334
|
-
}
|
|
4335
|
-
get isReorderEnabled() {
|
|
4336
|
-
return this.reorderRows;
|
|
4337
|
-
}
|
|
4338
|
-
getTbody() {
|
|
4339
|
-
return this.tableElement?.nativeElement.tBodies.item(0) ?? null;
|
|
4340
|
-
}
|
|
4341
|
-
setRowsDraggable(tbody, enabled) {
|
|
4342
|
-
const rows = Array.from(tbody.rows);
|
|
4343
|
-
rows.forEach((row) => {
|
|
4344
|
-
this.syncAutoDragHandle(row, enabled);
|
|
4345
|
-
row.draggable = false;
|
|
4346
|
-
if (!enabled) {
|
|
4347
|
-
delete row.dataset['dragging'];
|
|
4348
|
-
delete row.dataset['dragArmed'];
|
|
4349
|
-
}
|
|
4350
|
-
});
|
|
4351
|
-
}
|
|
4352
|
-
syncAutoDragHandle(row, enabled) {
|
|
4353
|
-
const firstCell = row.cells.item(0);
|
|
4354
|
-
if (!firstCell) {
|
|
4355
|
-
return;
|
|
4356
|
-
}
|
|
4357
|
-
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
4358
|
-
if (!enabled) {
|
|
4359
|
-
existingAutoHandle?.remove();
|
|
4360
|
-
return;
|
|
4361
|
-
}
|
|
4362
|
-
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
4363
|
-
if (hasCustomHandle || existingAutoHandle) {
|
|
4364
|
-
return;
|
|
4365
|
-
}
|
|
4366
|
-
const button = this.renderer.createElement('button');
|
|
4367
|
-
this.renderer.setAttribute(button, 'type', 'button');
|
|
4368
|
-
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
4369
|
-
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
4370
|
-
this.renderer.addClass(button, 'inline-flex');
|
|
4371
|
-
this.renderer.addClass(button, 'h-7');
|
|
4372
|
-
this.renderer.addClass(button, 'w-7');
|
|
4373
|
-
this.renderer.addClass(button, 'items-center');
|
|
4374
|
-
this.renderer.addClass(button, 'justify-center');
|
|
4375
|
-
this.renderer.addClass(button, 'cursor-grab');
|
|
4376
|
-
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
4377
|
-
this.renderer.addClass(button, 'text-muted-foreground');
|
|
4378
|
-
const dots = this.renderer.createElement('span');
|
|
4379
|
-
this.renderer.addClass(dots, 'text-sm');
|
|
4380
|
-
this.renderer.addClass(dots, 'leading-none');
|
|
4381
|
-
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
4382
|
-
this.renderer.appendChild(button, dots);
|
|
4383
|
-
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
4384
|
-
}
|
|
4385
|
-
onDragStart(event) {
|
|
4386
|
-
const target = event.target;
|
|
4387
|
-
const row = target?.closest('tr');
|
|
4388
|
-
if (!row) {
|
|
4389
|
-
return;
|
|
4390
|
-
}
|
|
4391
|
-
const handle = target?.closest(this.dragHandleSelector);
|
|
4392
|
-
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
4393
|
-
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
4394
|
-
event.preventDefault();
|
|
4395
|
-
return;
|
|
4396
|
-
}
|
|
4397
|
-
this.draggedRow = row;
|
|
4398
|
-
this.draggedRow.dataset['dragging'] = 'true';
|
|
4399
|
-
if (event.dataTransfer) {
|
|
4400
|
-
event.dataTransfer.effectAllowed = 'move';
|
|
4401
|
-
event.dataTransfer.setData('text/plain', '');
|
|
4402
|
-
}
|
|
4403
|
-
}
|
|
4404
|
-
onDragOver(event, tbody) {
|
|
4405
|
-
if (!this.draggedRow) {
|
|
4406
|
-
return;
|
|
4407
|
-
}
|
|
4408
|
-
event.preventDefault();
|
|
4409
|
-
const target = event.target;
|
|
4410
|
-
const targetRow = target?.closest('tr');
|
|
4411
|
-
if (!targetRow || targetRow === this.draggedRow) {
|
|
4412
|
-
return;
|
|
4413
|
-
}
|
|
4414
|
-
const rect = targetRow.getBoundingClientRect();
|
|
4415
|
-
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
4416
|
-
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
4417
|
-
}
|
|
4418
|
-
onDrop(event) {
|
|
4419
|
-
event.preventDefault();
|
|
4420
|
-
}
|
|
4421
|
-
onDragEnd() {
|
|
4422
|
-
const tbody = this.getTbody();
|
|
4423
|
-
if (tbody) {
|
|
4424
|
-
Array.from(tbody.rows).forEach((row) => {
|
|
4425
|
-
row.draggable = false;
|
|
4426
|
-
delete row.dataset['dragArmed'];
|
|
4427
|
-
});
|
|
4428
|
-
}
|
|
4429
|
-
if (this.draggedRow) {
|
|
4430
|
-
delete this.draggedRow.dataset['dragging'];
|
|
4431
|
-
this.draggedRow = null;
|
|
4432
|
-
}
|
|
4433
|
-
if (!tbody) {
|
|
4434
|
-
return;
|
|
4435
|
-
}
|
|
4436
|
-
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
4437
|
-
this.rowOrderChange.emit(order);
|
|
4438
|
-
}
|
|
4439
|
-
armDragFromHandle(event) {
|
|
4440
|
-
const target = event.target;
|
|
4441
|
-
const handle = target?.closest(this.dragHandleSelector);
|
|
4442
|
-
if (!handle) {
|
|
4443
|
-
return;
|
|
4444
|
-
}
|
|
4445
|
-
const row = handle.closest('tr');
|
|
4446
|
-
if (!row) {
|
|
4447
|
-
return;
|
|
4448
|
-
}
|
|
4449
|
-
row.draggable = true;
|
|
4450
|
-
row.dataset['dragArmed'] = 'true';
|
|
4451
|
-
}
|
|
4452
|
-
}
|
|
4453
|
-
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
4454
|
-
PdmTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTableComponent, selector: "pdm-table", inputs: { variant: "variant", reorderRows: "reorderRows", dragHandleSelector: "dragHandleSelector", className: "className" }, outputs: { rowOrderChange: "rowOrderChange" }, viewQueries: [{ propertyName: "tableElement", first: true, predicate: ["tableElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4455
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
4456
|
-
type: Component,
|
|
4457
|
-
args: [{ selector: 'pdm-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
|
|
4458
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
4459
|
-
type: Input
|
|
4460
|
-
}], reorderRows: [{
|
|
4461
|
-
type: Input
|
|
4462
|
-
}], dragHandleSelector: [{
|
|
4463
|
-
type: Input
|
|
4464
|
-
}], className: [{
|
|
4465
|
-
type: Input
|
|
4466
|
-
}], rowOrderChange: [{
|
|
4467
|
-
type: Output
|
|
4468
|
-
}], tableElement: [{
|
|
4469
|
-
type: ViewChild,
|
|
4470
|
-
args: ['tableElement']
|
|
4471
|
-
}] } });
|
|
4472
|
-
|
|
4473
5529
|
class PdmTabsComponent {
|
|
4474
5530
|
constructor(cdr) {
|
|
4475
5531
|
this.cdr = cdr;
|
|
@@ -4487,10 +5543,10 @@ class PdmTabsComponent {
|
|
|
4487
5543
|
}
|
|
4488
5544
|
}
|
|
4489
5545
|
PdmTabsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4490
|
-
PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div
|
|
5546
|
+
PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4491
5547
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, decorators: [{
|
|
4492
5548
|
type: Component,
|
|
4493
|
-
args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div
|
|
5549
|
+
args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
|
|
4494
5550
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
|
|
4495
5551
|
type: Input
|
|
4496
5552
|
}], value: [{
|
|
@@ -4641,10 +5697,10 @@ class PdmTooltipComponent {
|
|
|
4641
5697
|
}
|
|
4642
5698
|
}
|
|
4643
5699
|
PdmTooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4644
|
-
PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, ngImport: i0, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-
|
|
5700
|
+
PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, ngImport: i0, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4645
5701
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, decorators: [{
|
|
4646
5702
|
type: Component,
|
|
4647
|
-
args: [{ selector: 'pdm-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-
|
|
5703
|
+
args: [{ selector: 'pdm-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\n" }]
|
|
4648
5704
|
}], propDecorators: { text: [{
|
|
4649
5705
|
type: Input
|
|
4650
5706
|
}], side: [{
|
|
@@ -4675,6 +5731,7 @@ const COMPONENTS = [
|
|
|
4675
5731
|
PdmDataTableComponent,
|
|
4676
5732
|
PdmDatePickerComponent,
|
|
4677
5733
|
PdmDialogComponent,
|
|
5734
|
+
PdmDraggableTableComponent,
|
|
4678
5735
|
PdmDropdownMenuComponent,
|
|
4679
5736
|
PdmDrawerComponent,
|
|
4680
5737
|
PdmEmptyComponent,
|
|
@@ -4738,6 +5795,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4738
5795
|
PdmDataTableComponent,
|
|
4739
5796
|
PdmDatePickerComponent,
|
|
4740
5797
|
PdmDialogComponent,
|
|
5798
|
+
PdmDraggableTableComponent,
|
|
4741
5799
|
PdmDropdownMenuComponent,
|
|
4742
5800
|
PdmDrawerComponent,
|
|
4743
5801
|
PdmEmptyComponent,
|
|
@@ -4796,6 +5854,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4796
5854
|
PdmDataTableComponent,
|
|
4797
5855
|
PdmDatePickerComponent,
|
|
4798
5856
|
PdmDialogComponent,
|
|
5857
|
+
PdmDraggableTableComponent,
|
|
4799
5858
|
PdmDropdownMenuComponent,
|
|
4800
5859
|
PdmDrawerComponent,
|
|
4801
5860
|
PdmEmptyComponent,
|
|
@@ -4848,5 +5907,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4848
5907
|
* Generated bundle index. Do not edit.
|
|
4849
5908
|
*/
|
|
4850
5909
|
|
|
4851
|
-
export { PdmAccordionComponent, PdmAlertComponent, PdmAlertDialogComponent, PdmAspectRatioComponent, PdmAvatarComponent, PdmBadgeComponent, PdmBreadcrumbComponent, PdmButtonComponent, PdmButtonGroupComponent, PdmCalendarComponent, PdmCardComponent, PdmCarouselComponent, PdmChartComponent, PdmCheckboxComponent, PdmCollapsibleComponent, PdmComboboxComponent, PdmCommandComponent, PdmContextMenuComponent, PdmDataTableComponent, PdmDatePickerComponent, PdmDialogComponent, PdmDrawerComponent, PdmDropdownMenuComponent, PdmEmptyComponent, PdmFieldComponent, PdmHoverCardComponent, PdmIconComponent, PdmInputComponent, PdmInputGroupComponent, PdmInputOtpComponent, PdmInputPasswordComponent, PdmItemComponent, PdmKbdComponent, PdmLabelComponent, PdmMenubarComponent, PdmNativeSelectComponent, PdmNavigationMenuComponent, PdmOutsideClickDirective, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, createFlexiblePositionStrategy };
|
|
5910
|
+
export { BREAKPOINTS, PdmAccordionComponent, PdmAlertComponent, PdmAlertDialogComponent, PdmAspectRatioComponent, PdmAvatarComponent, PdmBadgeComponent, PdmBreadcrumbComponent, PdmButtonComponent, PdmButtonGroupComponent, PdmCalendarComponent, PdmCardComponent, PdmCarouselComponent, PdmChartComponent, PdmCheckboxComponent, PdmCollapsibleComponent, PdmComboboxComponent, PdmCommandComponent, PdmContextMenuComponent, PdmDataTableComponent, PdmDatePickerComponent, PdmDialogComponent, PdmDraggableTableComponent, PdmDrawerComponent, PdmDropdownMenuComponent, PdmEmptyComponent, PdmFieldComponent, PdmHoverCardComponent, PdmIconComponent, PdmInputComponent, PdmInputGroupComponent, PdmInputOtpComponent, PdmInputPasswordComponent, PdmItemComponent, PdmKbdComponent, PdmLabelComponent, PdmMenubarComponent, PdmNativeSelectComponent, PdmNavigationMenuComponent, PdmOutsideClickDirective, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, createFlexiblePositionStrategy, logZIndexStack, overflowResponsive, responsive, spacingResponsive, widthResponsive };
|
|
4852
5911
|
//# sourceMappingURL=pdm-ui-kit.mjs.map
|