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/fesm2015/pdm-ui-kit.mjs
CHANGED
|
@@ -132,10 +132,10 @@ class PdmAlertDialogComponent {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
PdmAlertDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
135
|
-
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-
|
|
135
|
+
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 });
|
|
136
136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, decorators: [{
|
|
137
137
|
type: Component,
|
|
138
|
-
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-
|
|
138
|
+
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" }]
|
|
139
139
|
}], propDecorators: { open: [{
|
|
140
140
|
type: Input
|
|
141
141
|
}], showTrigger: [{
|
|
@@ -256,30 +256,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
256
256
|
type: Input
|
|
257
257
|
}] } });
|
|
258
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Breadcrumb component con soporte responsive
|
|
261
|
+
*
|
|
262
|
+
* MEJORADO en v0.2.0:
|
|
263
|
+
* - Modo responsive real con overflow-x-auto
|
|
264
|
+
* - Collapse inteligente en mobile
|
|
265
|
+
*
|
|
266
|
+
* @example
|
|
267
|
+
* <pdm-breadcrumb
|
|
268
|
+
* mode="responsive"
|
|
269
|
+
* [items]="['Home', 'Products', 'Electronics', 'Laptops']">
|
|
270
|
+
* </pdm-breadcrumb>
|
|
271
|
+
*/
|
|
259
272
|
class PdmBreadcrumbComponent {
|
|
260
273
|
constructor() {
|
|
261
274
|
this.mode = 'link-component';
|
|
262
275
|
this.items = ['Home', 'Components', 'Breadcrumb'];
|
|
263
276
|
this.className = '';
|
|
277
|
+
/**
|
|
278
|
+
* Cantidad mínima de items para mostrar en mobile cuando mode="responsive"
|
|
279
|
+
* Default: 2 (primer y último item)
|
|
280
|
+
*/
|
|
281
|
+
this.minItemsMobile = 2;
|
|
264
282
|
}
|
|
265
283
|
get renderedItems() {
|
|
266
|
-
if (
|
|
284
|
+
if (this.mode === 'collapsed' && this.items.length > 3) {
|
|
267
285
|
return [this.items[0], '...', this.items[this.items.length - 2], this.items[this.items.length - 1]];
|
|
268
286
|
}
|
|
287
|
+
// Responsive mode: no collapse en el TS, se maneja en el template con CSS
|
|
269
288
|
return this.items;
|
|
270
289
|
}
|
|
290
|
+
/**
|
|
291
|
+
* Determina si un item debe estar visible en mobile (modo responsive)
|
|
292
|
+
*/
|
|
293
|
+
shouldShowInMobile(index) {
|
|
294
|
+
if (this.mode !== 'responsive')
|
|
295
|
+
return true;
|
|
296
|
+
const totalItems = this.items.length;
|
|
297
|
+
if (totalItems <= this.minItemsMobile)
|
|
298
|
+
return true;
|
|
299
|
+
// Siempre mostrar primero y último
|
|
300
|
+
return index === 0 || index === totalItems - 1;
|
|
301
|
+
}
|
|
271
302
|
}
|
|
272
303
|
PdmBreadcrumbComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
273
|
-
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'
|
|
304
|
+
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 });
|
|
274
305
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, decorators: [{
|
|
275
306
|
type: Component,
|
|
276
|
-
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
307
|
+
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" }]
|
|
277
308
|
}], propDecorators: { mode: [{
|
|
278
309
|
type: Input
|
|
279
310
|
}], items: [{
|
|
280
311
|
type: Input
|
|
281
312
|
}], className: [{
|
|
282
313
|
type: Input
|
|
314
|
+
}], minItemsMobile: [{
|
|
315
|
+
type: Input
|
|
283
316
|
}] } });
|
|
284
317
|
|
|
285
318
|
class PdmButtonGroupComponent {
|
|
@@ -1064,10 +1097,10 @@ class PdmCalendarComponent {
|
|
|
1064
1097
|
}
|
|
1065
1098
|
}
|
|
1066
1099
|
PdmCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1067
|
-
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 });
|
|
1100
|
+
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 });
|
|
1068
1101
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, decorators: [{
|
|
1069
1102
|
type: Component,
|
|
1070
|
-
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" }]
|
|
1103
|
+
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" }]
|
|
1071
1104
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { variant: [{
|
|
1072
1105
|
type: Input
|
|
1073
1106
|
}], className: [{
|
|
@@ -1205,66 +1238,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1205
1238
|
type: Output
|
|
1206
1239
|
}] } });
|
|
1207
1240
|
|
|
1241
|
+
/**
|
|
1242
|
+
* Card component - Visual container primitivo
|
|
1243
|
+
*
|
|
1244
|
+
* BREAKING CHANGE en v0.2.0: variant="login" eliminado.
|
|
1245
|
+
* Card es ahora un componente UI puro sin lógica de negocio.
|
|
1246
|
+
*
|
|
1247
|
+
* Para crear un login form, componer con primitivos:
|
|
1248
|
+
*
|
|
1249
|
+
* @example
|
|
1250
|
+
* <pdm-card>
|
|
1251
|
+
* <div pdmCardHeader>
|
|
1252
|
+
* <h3 class="text-lg font-semibold">Login</h3>
|
|
1253
|
+
* <p class="text-sm text-muted-foreground">Enter your credentials</p>
|
|
1254
|
+
* </div>
|
|
1255
|
+
* <div pdmCardContent>
|
|
1256
|
+
* <form [formGroup]="form">
|
|
1257
|
+
* <pdm-field>
|
|
1258
|
+
* <pdm-label>Email</pdm-label>
|
|
1259
|
+
* <pdm-input type="email" formControlName="email" />
|
|
1260
|
+
* </pdm-field>
|
|
1261
|
+
* <pdm-field>
|
|
1262
|
+
* <pdm-label>Password</pdm-label>
|
|
1263
|
+
* <pdm-input-password formControlName="password" />
|
|
1264
|
+
* </pdm-field>
|
|
1265
|
+
* </form>
|
|
1266
|
+
* </div>
|
|
1267
|
+
* <div pdmCardFooter>
|
|
1268
|
+
* <pdm-button (click)="onLogin()">Login</pdm-button>
|
|
1269
|
+
* </div>
|
|
1270
|
+
* </pdm-card>
|
|
1271
|
+
*/
|
|
1208
1272
|
class PdmCardComponent {
|
|
1209
1273
|
constructor() {
|
|
1210
|
-
this.variant = 'default';
|
|
1211
1274
|
this.className = '';
|
|
1212
|
-
this.title = 'Login to your account';
|
|
1213
|
-
this.description = 'Enter your email below to login to your account';
|
|
1214
|
-
this.actionText = 'Sign up';
|
|
1215
|
-
this.emailLabel = 'Email';
|
|
1216
|
-
this.emailPlaceholder = 'm@example.com';
|
|
1217
|
-
this.passwordLabel = 'Password';
|
|
1218
|
-
this.passwordHint = 'Forgot password?';
|
|
1219
|
-
this.primaryActionText = 'Login';
|
|
1220
|
-
this.secondaryActionText = 'Login with Google';
|
|
1221
|
-
this.primaryAction = new EventEmitter();
|
|
1222
|
-
this.secondaryAction = new EventEmitter();
|
|
1223
|
-
this.actionPressed = new EventEmitter();
|
|
1224
|
-
}
|
|
1225
|
-
onPrimaryAction() {
|
|
1226
|
-
this.primaryAction.emit();
|
|
1227
|
-
}
|
|
1228
|
-
onSecondaryAction() {
|
|
1229
|
-
this.secondaryAction.emit();
|
|
1230
|
-
}
|
|
1231
|
-
onActionPressed() {
|
|
1232
|
-
this.actionPressed.emit();
|
|
1233
1275
|
}
|
|
1234
1276
|
}
|
|
1235
1277
|
PdmCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1236
|
-
PdmCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCardComponent, selector: "pdm-card", inputs: {
|
|
1278
|
+
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 });
|
|
1237
1279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, decorators: [{
|
|
1238
1280
|
type: Component,
|
|
1239
|
-
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 <
|
|
1240
|
-
}], propDecorators: {
|
|
1241
|
-
type: Input
|
|
1242
|
-
}], className: [{
|
|
1243
|
-
type: Input
|
|
1244
|
-
}], title: [{
|
|
1245
|
-
type: Input
|
|
1246
|
-
}], description: [{
|
|
1247
|
-
type: Input
|
|
1248
|
-
}], actionText: [{
|
|
1249
|
-
type: Input
|
|
1250
|
-
}], emailLabel: [{
|
|
1251
|
-
type: Input
|
|
1252
|
-
}], emailPlaceholder: [{
|
|
1253
|
-
type: Input
|
|
1254
|
-
}], passwordLabel: [{
|
|
1255
|
-
type: Input
|
|
1256
|
-
}], passwordHint: [{
|
|
1257
|
-
type: Input
|
|
1258
|
-
}], primaryActionText: [{
|
|
1259
|
-
type: Input
|
|
1260
|
-
}], secondaryActionText: [{
|
|
1281
|
+
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" }]
|
|
1282
|
+
}], propDecorators: { className: [{
|
|
1261
1283
|
type: Input
|
|
1262
|
-
}], primaryAction: [{
|
|
1263
|
-
type: Output
|
|
1264
|
-
}], secondaryAction: [{
|
|
1265
|
-
type: Output
|
|
1266
|
-
}], actionPressed: [{
|
|
1267
|
-
type: Output
|
|
1268
1284
|
}] } });
|
|
1269
1285
|
|
|
1270
1286
|
class PdmChartComponent {
|
|
@@ -1764,10 +1780,10 @@ class PdmCommandComponent {
|
|
|
1764
1780
|
}
|
|
1765
1781
|
}
|
|
1766
1782
|
PdmCommandComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1767
|
-
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-
|
|
1783
|
+
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 });
|
|
1768
1784
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, decorators: [{
|
|
1769
1785
|
type: Component,
|
|
1770
|
-
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-
|
|
1786
|
+
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" }]
|
|
1771
1787
|
}], propDecorators: { open: [{
|
|
1772
1788
|
type: Input
|
|
1773
1789
|
}], hintLabel: [{
|
|
@@ -1850,10 +1866,10 @@ class PdmContextMenuComponent {
|
|
|
1850
1866
|
}
|
|
1851
1867
|
}
|
|
1852
1868
|
PdmContextMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1853
|
-
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-
|
|
1869
|
+
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 });
|
|
1854
1870
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, decorators: [{
|
|
1855
1871
|
type: Component,
|
|
1856
|
-
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-
|
|
1872
|
+
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" }]
|
|
1857
1873
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { items: [{
|
|
1858
1874
|
type: Input
|
|
1859
1875
|
}], className: [{
|
|
@@ -1871,31 +1887,459 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1871
1887
|
args: ['document:keydown.escape']
|
|
1872
1888
|
}] } });
|
|
1873
1889
|
|
|
1890
|
+
/**
|
|
1891
|
+
* Sistema de responsive utilities para PDM UI Kit
|
|
1892
|
+
*
|
|
1893
|
+
* Proporciona constantes, tipos y helpers para manejar responsive design
|
|
1894
|
+
* de forma consistente en todos los componentes.
|
|
1895
|
+
*/
|
|
1896
|
+
/**
|
|
1897
|
+
* Breakpoints estándar de Tailwind CSS
|
|
1898
|
+
* Mobile-first approach: los estilos base son para mobile, los breakpoints son MIN-WIDTH
|
|
1899
|
+
*/
|
|
1900
|
+
const BREAKPOINTS = {
|
|
1901
|
+
sm: '640px',
|
|
1902
|
+
md: '768px',
|
|
1903
|
+
lg: '1024px',
|
|
1904
|
+
xl: '1280px',
|
|
1905
|
+
'2xl': '1536px' // extra large desktop
|
|
1906
|
+
};
|
|
1907
|
+
/**
|
|
1908
|
+
* Helper para generar clases responsive de forma programática
|
|
1909
|
+
*
|
|
1910
|
+
* @example
|
|
1911
|
+
* responsive({ default: 'block', sm: 'flex', lg: 'grid' })
|
|
1912
|
+
* // Returns: 'block sm:flex lg:grid'
|
|
1913
|
+
*/
|
|
1914
|
+
function responsive(config) {
|
|
1915
|
+
const classes = [];
|
|
1916
|
+
if (config.default) {
|
|
1917
|
+
classes.push(config.default);
|
|
1918
|
+
}
|
|
1919
|
+
['sm', 'md', 'lg', 'xl', '2xl'].forEach(bp => {
|
|
1920
|
+
if (config[bp]) {
|
|
1921
|
+
classes.push(`${bp}:${config[bp]}`);
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
return classes.join(' ');
|
|
1925
|
+
}
|
|
1926
|
+
/**
|
|
1927
|
+
* Helper para overflow responsive
|
|
1928
|
+
* Maneja el caso común de scroll en mobile, auto en desktop
|
|
1929
|
+
*
|
|
1930
|
+
* @example
|
|
1931
|
+
* overflowResponsive('x', 'scroll', 'auto')
|
|
1932
|
+
* // Returns: 'overflow-x-scroll sm:overflow-x-auto'
|
|
1933
|
+
*/
|
|
1934
|
+
function overflowResponsive(axis, mobile, desktop) {
|
|
1935
|
+
const axisClass = axis === 'both' ? 'overflow' : `overflow-${axis}`;
|
|
1936
|
+
const mobileClass = `${axisClass}-${mobile}`;
|
|
1937
|
+
if (!desktop || desktop === mobile) {
|
|
1938
|
+
return mobileClass;
|
|
1939
|
+
}
|
|
1940
|
+
return `${mobileClass} sm:${axisClass}-${desktop}`;
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Helper para spacing responsive
|
|
1944
|
+
* Útil para padding/margin que necesita ajustarse por breakpoint
|
|
1945
|
+
*
|
|
1946
|
+
* @example
|
|
1947
|
+
* spacingResponsive('px', { default: '4', sm: '6', lg: '8' })
|
|
1948
|
+
* // Returns: 'px-4 sm:px-6 lg:px-8'
|
|
1949
|
+
*/
|
|
1950
|
+
function spacingResponsive(property, values) {
|
|
1951
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1952
|
+
acc[key] = `${property}-${value}`;
|
|
1953
|
+
return acc;
|
|
1954
|
+
}, {}));
|
|
1955
|
+
}
|
|
1956
|
+
/**
|
|
1957
|
+
* Helper para width responsive
|
|
1958
|
+
*
|
|
1959
|
+
* @example
|
|
1960
|
+
* widthResponsive({ default: 'full', sm: 'auto', lg: '1/2' })
|
|
1961
|
+
* // Returns: 'w-full sm:w-auto lg:w-1/2'
|
|
1962
|
+
*/
|
|
1963
|
+
function widthResponsive(values) {
|
|
1964
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1965
|
+
acc[key] = `w-${value}`;
|
|
1966
|
+
return acc;
|
|
1967
|
+
}, {}));
|
|
1968
|
+
}
|
|
1969
|
+
/**
|
|
1970
|
+
* Clases comunes para containers responsive
|
|
1971
|
+
* Pensadas para wrappers que contienen contenido que puede desbordar
|
|
1972
|
+
*/
|
|
1973
|
+
const RESPONSIVE_CONTAINER = {
|
|
1974
|
+
// Container con scroll horizontal en mobile, contenido visible en desktop
|
|
1975
|
+
tableWrapper: 'relative w-full overflow-x-auto sm:overflow-x-visible',
|
|
1976
|
+
// Container con padding negativo en mobile para scroll edge-to-edge
|
|
1977
|
+
tableWrapperFullBleed: 'relative w-full -mx-4 px-4 overflow-x-auto sm:mx-0 sm:px-0 sm:overflow-x-visible',
|
|
1978
|
+
// Container con max-width responsive
|
|
1979
|
+
contentWrapper: 'w-full mx-auto px-4 sm:px-6 lg:px-8 max-w-screen-2xl',
|
|
1980
|
+
// Container para modals/dialogs
|
|
1981
|
+
modalWrapper: 'w-full max-w-lg mx-auto px-4 sm:px-0',
|
|
1982
|
+
// Container para forms
|
|
1983
|
+
formWrapper: 'w-full max-w-md mx-auto space-y-4'
|
|
1984
|
+
};
|
|
1985
|
+
/**
|
|
1986
|
+
* Clases comunes para display responsive
|
|
1987
|
+
*/
|
|
1988
|
+
const RESPONSIVE_DISPLAY = {
|
|
1989
|
+
// Ocultar en mobile, mostrar en desktop
|
|
1990
|
+
hideOnMobile: 'hidden sm:block',
|
|
1991
|
+
// Mostrar solo en mobile
|
|
1992
|
+
showOnMobile: 'block sm:hidden',
|
|
1993
|
+
// Stack en mobile, flex en desktop
|
|
1994
|
+
stackToFlex: 'flex flex-col sm:flex-row',
|
|
1995
|
+
// Stack en mobile, grid en desktop
|
|
1996
|
+
stackToGrid: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'
|
|
1997
|
+
};
|
|
1998
|
+
/**
|
|
1999
|
+
* Clases para table responsive strategies
|
|
2000
|
+
*/
|
|
2001
|
+
const TABLE_RESPONSIVE = {
|
|
2002
|
+
// Scroll horizontal (default, más simple)
|
|
2003
|
+
scroll: {
|
|
2004
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2005
|
+
table: 'w-full min-w-full',
|
|
2006
|
+
cell: 'whitespace-nowrap'
|
|
2007
|
+
},
|
|
2008
|
+
// Permitir wrap del contenido
|
|
2009
|
+
wrap: {
|
|
2010
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2011
|
+
table: 'w-full',
|
|
2012
|
+
cell: 'whitespace-normal break-words'
|
|
2013
|
+
},
|
|
2014
|
+
// Stack en mobile (cada fila se convierte en card)
|
|
2015
|
+
// Requiere lógica adicional en el componente
|
|
2016
|
+
stack: {
|
|
2017
|
+
wrapper: 'relative w-full',
|
|
2018
|
+
table: 'w-full',
|
|
2019
|
+
row: 'block sm:table-row border-b sm:border-b-0',
|
|
2020
|
+
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'
|
|
2021
|
+
},
|
|
2022
|
+
// Collapse: ocultar columnas menos importantes en mobile
|
|
2023
|
+
// Se usa con clases de visibility en las columnas específicas
|
|
2024
|
+
collapse: {
|
|
2025
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2026
|
+
table: 'w-full',
|
|
2027
|
+
cell: 'whitespace-nowrap',
|
|
2028
|
+
// Estas clases se aplican a columnas opcionales
|
|
2029
|
+
optionalColumn: 'hidden md:table-cell'
|
|
2030
|
+
}
|
|
2031
|
+
};
|
|
2032
|
+
|
|
2033
|
+
/**
|
|
2034
|
+
* Componente base de tabla con soporte responsive
|
|
2035
|
+
*
|
|
2036
|
+
* SIMPLIFICADO: Ya no incluye drag & drop (usar pdm-draggable-table para eso)
|
|
2037
|
+
*
|
|
2038
|
+
* @example
|
|
2039
|
+
* // Tabla simple con scroll horizontal
|
|
2040
|
+
* <pdm-table variant="default">
|
|
2041
|
+
* <thead><tr><th>Name</th><th>Email</th></tr></thead>
|
|
2042
|
+
* <tbody><tr><td>John</td><td>john@example.com</td></tr></tbody>
|
|
2043
|
+
* </pdm-table>
|
|
2044
|
+
*
|
|
2045
|
+
* @example
|
|
2046
|
+
* // Tabla interactiva con wrap en mobile
|
|
2047
|
+
* <pdm-table variant="interactive" responsiveStrategy="wrap">
|
|
2048
|
+
* ...
|
|
2049
|
+
* </pdm-table>
|
|
2050
|
+
*/
|
|
2051
|
+
class PdmTableComponent {
|
|
2052
|
+
constructor() {
|
|
2053
|
+
/**
|
|
2054
|
+
* Variante visual de la tabla
|
|
2055
|
+
* - default: tabla básica sin estilos extra
|
|
2056
|
+
* - data: tabla con bordes y espaciado para data
|
|
2057
|
+
* - interactive: tabla con hover, sticky header y estilos interactivos
|
|
2058
|
+
*/
|
|
2059
|
+
this.variant = 'default';
|
|
2060
|
+
/**
|
|
2061
|
+
* Estrategia responsive para la tabla
|
|
2062
|
+
* - scroll: scroll horizontal en mobile (default, más simple)
|
|
2063
|
+
* - wrap: permite que el contenido haga wrap
|
|
2064
|
+
* - stack: convierte filas en cards en mobile (requiere data-label en celdas)
|
|
2065
|
+
* - collapse: oculta columnas menos importantes en mobile
|
|
2066
|
+
*/
|
|
2067
|
+
this.responsiveStrategy = 'scroll';
|
|
2068
|
+
/**
|
|
2069
|
+
* Clases CSS adicionales para el wrapper
|
|
2070
|
+
*/
|
|
2071
|
+
this.className = '';
|
|
2072
|
+
/**
|
|
2073
|
+
* Si es true, aplica padding negativo en mobile para scroll edge-to-edge
|
|
2074
|
+
* Útil cuando la tabla está dentro de un container con padding
|
|
2075
|
+
*/
|
|
2076
|
+
this.fullBleed = false;
|
|
2077
|
+
}
|
|
2078
|
+
get wrapperClasses() {
|
|
2079
|
+
const baseClasses = ['relative', 'w-full'];
|
|
2080
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
2081
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
2082
|
+
// Full bleed: scroll edge-to-edge en mobile
|
|
2083
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
2084
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
2085
|
+
}
|
|
2086
|
+
return [
|
|
2087
|
+
...baseClasses,
|
|
2088
|
+
...strategyClasses,
|
|
2089
|
+
...variantClasses,
|
|
2090
|
+
this.className
|
|
2091
|
+
].filter(Boolean);
|
|
2092
|
+
}
|
|
2093
|
+
get tableClasses() {
|
|
2094
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
2095
|
+
const variantClasses = this.getVariantTableClasses();
|
|
2096
|
+
const cellClasses = this.getCellClasses();
|
|
2097
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
2098
|
+
}
|
|
2099
|
+
getResponsiveStrategyClasses() {
|
|
2100
|
+
const strategy = TABLE_RESPONSIVE[this.responsiveStrategy];
|
|
2101
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2102
|
+
return ['overflow-x-auto'];
|
|
2103
|
+
}
|
|
2104
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2105
|
+
return ['overflow-x-auto'];
|
|
2106
|
+
}
|
|
2107
|
+
if (this.responsiveStrategy === 'stack') {
|
|
2108
|
+
// Stack requiere lógica en el template, aquí solo el wrapper
|
|
2109
|
+
return [];
|
|
2110
|
+
}
|
|
2111
|
+
if (this.responsiveStrategy === 'collapse') {
|
|
2112
|
+
return ['overflow-x-auto'];
|
|
2113
|
+
}
|
|
2114
|
+
return ['overflow-auto'];
|
|
2115
|
+
}
|
|
2116
|
+
getVariantWrapperClasses() {
|
|
2117
|
+
if (this.variant === 'interactive') {
|
|
2118
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
2119
|
+
}
|
|
2120
|
+
if (this.variant === 'data') {
|
|
2121
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
2122
|
+
}
|
|
2123
|
+
return [];
|
|
2124
|
+
}
|
|
2125
|
+
getVariantTableClasses() {
|
|
2126
|
+
if (this.variant === 'data') {
|
|
2127
|
+
return [
|
|
2128
|
+
'border-collapse',
|
|
2129
|
+
'text-foreground',
|
|
2130
|
+
'[&_thead_tr]:border-b',
|
|
2131
|
+
'[&_thead_tr]:border-border',
|
|
2132
|
+
'[&_tbody_tr]:border-b',
|
|
2133
|
+
'[&_tbody_tr]:border-border',
|
|
2134
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2135
|
+
'[&_th]:h-10',
|
|
2136
|
+
'[&_th]:px-2',
|
|
2137
|
+
'[&_th]:text-left',
|
|
2138
|
+
'[&_th]:align-middle',
|
|
2139
|
+
'[&_th]:font-medium',
|
|
2140
|
+
'[&_td]:p-2',
|
|
2141
|
+
'[&_td]:align-middle'
|
|
2142
|
+
];
|
|
2143
|
+
}
|
|
2144
|
+
if (this.variant === 'interactive') {
|
|
2145
|
+
return [
|
|
2146
|
+
'text-foreground',
|
|
2147
|
+
'[&_thead]:sticky',
|
|
2148
|
+
'[&_thead]:top-0',
|
|
2149
|
+
'[&_thead]:z-10',
|
|
2150
|
+
'[&_thead]:bg-muted/70',
|
|
2151
|
+
'[&_thead_tr]:border-b',
|
|
2152
|
+
'[&_thead_tr]:border-border',
|
|
2153
|
+
'[&_th]:h-12',
|
|
2154
|
+
'[&_th]:px-4',
|
|
2155
|
+
'[&_th]:text-left',
|
|
2156
|
+
'[&_th]:align-middle',
|
|
2157
|
+
'[&_th]:text-sm',
|
|
2158
|
+
'[&_th]:font-medium',
|
|
2159
|
+
'[&_tbody_tr]:border-b',
|
|
2160
|
+
'[&_tbody_tr]:border-border',
|
|
2161
|
+
'[&_tbody_tr]:transition-colors',
|
|
2162
|
+
'[&_tbody_tr:hover]:bg-muted/50',
|
|
2163
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2164
|
+
'[&_td]:h-14',
|
|
2165
|
+
'[&_td]:px-4',
|
|
2166
|
+
'[&_td]:align-middle',
|
|
2167
|
+
'[&_td]:text-sm',
|
|
2168
|
+
'[&_svg]:text-muted-foreground'
|
|
2169
|
+
];
|
|
2170
|
+
}
|
|
2171
|
+
return [];
|
|
2172
|
+
}
|
|
2173
|
+
getCellClasses() {
|
|
2174
|
+
// Manejo responsive de whitespace
|
|
2175
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2176
|
+
// En scroll, permitir wrap en mobile, nowrap en desktop
|
|
2177
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
2178
|
+
}
|
|
2179
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2180
|
+
// En wrap, siempre permitir wrap
|
|
2181
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
2182
|
+
}
|
|
2183
|
+
// Default: nowrap (comportamiento anterior para backward compatibility)
|
|
2184
|
+
return [];
|
|
2185
|
+
}
|
|
2186
|
+
}
|
|
2187
|
+
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2188
|
+
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 });
|
|
2189
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
2190
|
+
type: Component,
|
|
2191
|
+
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" }]
|
|
2192
|
+
}], propDecorators: { variant: [{
|
|
2193
|
+
type: Input
|
|
2194
|
+
}], responsiveStrategy: [{
|
|
2195
|
+
type: Input
|
|
2196
|
+
}], className: [{
|
|
2197
|
+
type: Input
|
|
2198
|
+
}], fullBleed: [{
|
|
2199
|
+
type: Input
|
|
2200
|
+
}] } });
|
|
2201
|
+
|
|
2202
|
+
/**
|
|
2203
|
+
* Data-table genérico con paginación, filtrado y selección
|
|
2204
|
+
*
|
|
2205
|
+
* NUEVO: Ahora es genérico y configurable via columnas
|
|
2206
|
+
*
|
|
2207
|
+
* @example
|
|
2208
|
+
* // Definir columnas
|
|
2209
|
+
* columns: PdmDataTableColumn<User>[] = [
|
|
2210
|
+
* { key: 'name', label: 'Name', sortable: true },
|
|
2211
|
+
* { key: 'email', label: 'Email', sortable: true },
|
|
2212
|
+
* { key: 'role', label: 'Role', hideOnMobile: true },
|
|
2213
|
+
* { key: 'createdAt', label: 'Created', render: (val) => formatDate(val) }
|
|
2214
|
+
* ];
|
|
2215
|
+
*
|
|
2216
|
+
* // En el template
|
|
2217
|
+
* <pdm-data-table
|
|
2218
|
+
* [columns]="columns"
|
|
2219
|
+
* [rows]="users"
|
|
2220
|
+
* [selectable]="true"
|
|
2221
|
+
* (selectionChange)="onSelect($event)">
|
|
2222
|
+
* </pdm-data-table>
|
|
2223
|
+
*/
|
|
1874
2224
|
class PdmDataTableComponent {
|
|
1875
2225
|
constructor() {
|
|
1876
2226
|
this.className = '';
|
|
2227
|
+
/**
|
|
2228
|
+
* Columnas a mostrar
|
|
2229
|
+
* Si no se provee, intenta inferir del primer row (legacy mode)
|
|
2230
|
+
*/
|
|
2231
|
+
this.columns = [];
|
|
2232
|
+
/**
|
|
2233
|
+
* Estrategia responsive de la tabla
|
|
2234
|
+
*/
|
|
2235
|
+
this.responsiveStrategy = 'scroll';
|
|
2236
|
+
/**
|
|
2237
|
+
* Si es true, muestra checkbox de selección en cada fila
|
|
2238
|
+
*/
|
|
2239
|
+
this.selectable = false;
|
|
2240
|
+
/**
|
|
2241
|
+
* Si es true, muestra botón de acciones (tres puntos) en cada fila
|
|
2242
|
+
*/
|
|
2243
|
+
this.showActions = false;
|
|
2244
|
+
/**
|
|
2245
|
+
* Si es true, muestra filtro de búsqueda
|
|
2246
|
+
*/
|
|
2247
|
+
this.showFilter = true;
|
|
2248
|
+
/**
|
|
2249
|
+
* Si es true, muestra controles de paginación
|
|
2250
|
+
*/
|
|
2251
|
+
this.showPagination = true;
|
|
2252
|
+
/**
|
|
2253
|
+
* Si es true, muestra selector de columnas
|
|
2254
|
+
*/
|
|
2255
|
+
this.showColumnSelector = false;
|
|
2256
|
+
// Labels i18n
|
|
1877
2257
|
this.filterPlaceholder = 'Filter...';
|
|
1878
2258
|
this.columnsLabel = 'Columns';
|
|
1879
|
-
this.statusLabel = 'Status';
|
|
1880
|
-
this.emailLabel = 'Email';
|
|
1881
|
-
this.amountLabel = 'Amount';
|
|
1882
2259
|
this.previousLabel = 'Previous';
|
|
1883
2260
|
this.nextLabel = 'Next';
|
|
1884
2261
|
this.emptyLabel = 'No results.';
|
|
2262
|
+
this.rowsSelectedLabel = 'row(s) selected';
|
|
2263
|
+
// DEPRECATED: Labels hardcodeados para backward compatibility
|
|
2264
|
+
/**
|
|
2265
|
+
* @deprecated Use columns configuration instead
|
|
2266
|
+
*/
|
|
2267
|
+
this.statusLabel = 'Status';
|
|
2268
|
+
/**
|
|
2269
|
+
* @deprecated Use columns configuration instead
|
|
2270
|
+
*/
|
|
2271
|
+
this.emailLabel = 'Email';
|
|
2272
|
+
/**
|
|
2273
|
+
* @deprecated Use columns configuration instead
|
|
2274
|
+
*/
|
|
2275
|
+
this.amountLabel = 'Amount';
|
|
2276
|
+
/**
|
|
2277
|
+
* Datos a mostrar
|
|
2278
|
+
*/
|
|
1885
2279
|
this.rows = [];
|
|
2280
|
+
/**
|
|
2281
|
+
* Página actual (1-indexed)
|
|
2282
|
+
*/
|
|
1886
2283
|
this.page = 1;
|
|
1887
|
-
|
|
2284
|
+
/**
|
|
2285
|
+
* Cantidad de filas por página
|
|
2286
|
+
*/
|
|
2287
|
+
this.pageSize = 10;
|
|
2288
|
+
/**
|
|
2289
|
+
* Query de filtrado
|
|
2290
|
+
*/
|
|
1888
2291
|
this.query = '';
|
|
1889
2292
|
this.queryChange = new EventEmitter();
|
|
1890
2293
|
this.rowAction = new EventEmitter();
|
|
1891
2294
|
this.pageChange = new EventEmitter();
|
|
1892
2295
|
this.selectionChange = new EventEmitter();
|
|
2296
|
+
this.columnSort = new EventEmitter();
|
|
2297
|
+
// Estado interno
|
|
2298
|
+
this.selectedRows = new Set();
|
|
2299
|
+
this.sortDirection = 'asc';
|
|
2300
|
+
}
|
|
2301
|
+
/**
|
|
2302
|
+
* Backward compatibility: si no hay columnas definidas, inferir del primer row
|
|
2303
|
+
*/
|
|
2304
|
+
get effectiveColumns() {
|
|
2305
|
+
if (this.columns.length > 0) {
|
|
2306
|
+
return this.columns;
|
|
2307
|
+
}
|
|
2308
|
+
// Legacy mode: inferir columnas del primer row (solo para PdmDataTableRow)
|
|
2309
|
+
if (this.rows.length > 0) {
|
|
2310
|
+
const firstRow = this.rows[0];
|
|
2311
|
+
return Object.keys(firstRow)
|
|
2312
|
+
.filter(key => key !== 'selected')
|
|
2313
|
+
.map(key => ({
|
|
2314
|
+
key: key,
|
|
2315
|
+
label: this.getLegacyLabel(key),
|
|
2316
|
+
align: key === 'amount' ? 'right' : 'left'
|
|
2317
|
+
}));
|
|
2318
|
+
}
|
|
2319
|
+
return [];
|
|
2320
|
+
}
|
|
2321
|
+
/**
|
|
2322
|
+
* LEGACY: mapeo de keys a labels hardcodeados
|
|
2323
|
+
*/
|
|
2324
|
+
getLegacyLabel(key) {
|
|
2325
|
+
const map = {
|
|
2326
|
+
status: this.statusLabel,
|
|
2327
|
+
email: this.emailLabel,
|
|
2328
|
+
amount: this.amountLabel
|
|
2329
|
+
};
|
|
2330
|
+
return map[key] || key.charAt(0).toUpperCase() + key.slice(1);
|
|
1893
2331
|
}
|
|
1894
2332
|
get filteredRows() {
|
|
1895
2333
|
const q = this.query.trim().toLowerCase();
|
|
1896
2334
|
if (!q)
|
|
1897
2335
|
return this.rows;
|
|
1898
|
-
|
|
2336
|
+
if (this.filterFn) {
|
|
2337
|
+
return this.rows.filter(row => this.filterFn(row, q));
|
|
2338
|
+
}
|
|
2339
|
+
// Filtrado default: buscar en todos los campos string
|
|
2340
|
+
return this.rows.filter(row => {
|
|
2341
|
+
return Object.values(row).some(val => typeof val === 'string' && val.toLowerCase().includes(q));
|
|
2342
|
+
});
|
|
1899
2343
|
}
|
|
1900
2344
|
get pagedRows() {
|
|
1901
2345
|
const start = (this.page - 1) * this.pageSize;
|
|
@@ -1905,14 +2349,33 @@ class PdmDataTableComponent {
|
|
|
1905
2349
|
return Math.max(1, Math.ceil(this.filteredRows.length / this.pageSize));
|
|
1906
2350
|
}
|
|
1907
2351
|
get selectedCount() {
|
|
1908
|
-
return this.
|
|
2352
|
+
return this.selectedRows.size;
|
|
1909
2353
|
}
|
|
1910
2354
|
onQueryInput(event) {
|
|
1911
2355
|
const value = event.target.value;
|
|
1912
2356
|
this.queryChange.emit(value);
|
|
1913
2357
|
}
|
|
1914
2358
|
onToggleRow(row, event) {
|
|
1915
|
-
|
|
2359
|
+
const checked = event.target.checked;
|
|
2360
|
+
if (checked) {
|
|
2361
|
+
this.selectedRows.add(row);
|
|
2362
|
+
}
|
|
2363
|
+
else {
|
|
2364
|
+
this.selectedRows.delete(row);
|
|
2365
|
+
}
|
|
2366
|
+
this.selectionChange.emit({ row, selected: checked });
|
|
2367
|
+
}
|
|
2368
|
+
onToggleAll(event) {
|
|
2369
|
+
const checked = event.target.checked;
|
|
2370
|
+
if (checked) {
|
|
2371
|
+
this.pagedRows.forEach(row => this.selectedRows.add(row));
|
|
2372
|
+
}
|
|
2373
|
+
else {
|
|
2374
|
+
this.pagedRows.forEach(row => this.selectedRows.delete(row));
|
|
2375
|
+
}
|
|
2376
|
+
}
|
|
2377
|
+
isSelected(row) {
|
|
2378
|
+
return this.selectedRows.has(row);
|
|
1916
2379
|
}
|
|
1917
2380
|
previous() {
|
|
1918
2381
|
if (this.page <= 1)
|
|
@@ -1925,25 +2388,75 @@ class PdmDataTableComponent {
|
|
|
1925
2388
|
this.pageChange.emit(this.page + 1);
|
|
1926
2389
|
}
|
|
1927
2390
|
onAction(row) {
|
|
1928
|
-
this.rowAction.emit(row
|
|
2391
|
+
this.rowAction.emit(row);
|
|
2392
|
+
}
|
|
2393
|
+
onSort(column) {
|
|
2394
|
+
if (!column.sortable)
|
|
2395
|
+
return;
|
|
2396
|
+
if (this.sortColumn === column) {
|
|
2397
|
+
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
|
2398
|
+
}
|
|
2399
|
+
else {
|
|
2400
|
+
this.sortColumn = column;
|
|
2401
|
+
this.sortDirection = 'asc';
|
|
2402
|
+
}
|
|
2403
|
+
this.columnSort.emit({ column, direction: this.sortDirection });
|
|
2404
|
+
}
|
|
2405
|
+
getCellValue(row, column) {
|
|
2406
|
+
const value = row[column.key];
|
|
2407
|
+
if (column.render) {
|
|
2408
|
+
return column.render(value, row);
|
|
2409
|
+
}
|
|
2410
|
+
return value != null ? String(value) : '';
|
|
2411
|
+
}
|
|
2412
|
+
getCellClass(column) {
|
|
2413
|
+
const classes = ['px-2', 'py-2'];
|
|
2414
|
+
if (column.align === 'center')
|
|
2415
|
+
classes.push('text-center');
|
|
2416
|
+
if (column.align === 'right')
|
|
2417
|
+
classes.push('text-right');
|
|
2418
|
+
if (column.hideOnMobile)
|
|
2419
|
+
classes.push('hidden', 'md:table-cell');
|
|
2420
|
+
if (column.cellClass)
|
|
2421
|
+
classes.push(column.cellClass);
|
|
2422
|
+
return classes.join(' ');
|
|
2423
|
+
}
|
|
2424
|
+
getHeaderClass(column) {
|
|
2425
|
+
const classes = ['px-2', 'py-2', 'text-left', 'font-medium'];
|
|
2426
|
+
if (column.hideOnMobile)
|
|
2427
|
+
classes.push('hidden', 'md:table-cell');
|
|
2428
|
+
if (column.headerClass)
|
|
2429
|
+
classes.push(column.headerClass);
|
|
2430
|
+
return classes.join(' ');
|
|
2431
|
+
}
|
|
2432
|
+
getColumnStyle(column) {
|
|
2433
|
+
return column.width ? { width: column.width } : {};
|
|
1929
2434
|
}
|
|
1930
2435
|
}
|
|
1931
2436
|
PdmDataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1932
|
-
PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className",
|
|
2437
|
+
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 });
|
|
1933
2438
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, decorators: [{
|
|
1934
2439
|
type: Component,
|
|
1935
|
-
args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full
|
|
2440
|
+
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" }]
|
|
1936
2441
|
}], propDecorators: { className: [{
|
|
1937
2442
|
type: Input
|
|
1938
|
-
}],
|
|
2443
|
+
}], columns: [{
|
|
1939
2444
|
type: Input
|
|
1940
|
-
}],
|
|
2445
|
+
}], responsiveStrategy: [{
|
|
1941
2446
|
type: Input
|
|
1942
|
-
}],
|
|
2447
|
+
}], selectable: [{
|
|
1943
2448
|
type: Input
|
|
1944
|
-
}],
|
|
2449
|
+
}], showActions: [{
|
|
1945
2450
|
type: Input
|
|
1946
|
-
}],
|
|
2451
|
+
}], showFilter: [{
|
|
2452
|
+
type: Input
|
|
2453
|
+
}], showPagination: [{
|
|
2454
|
+
type: Input
|
|
2455
|
+
}], showColumnSelector: [{
|
|
2456
|
+
type: Input
|
|
2457
|
+
}], filterPlaceholder: [{
|
|
2458
|
+
type: Input
|
|
2459
|
+
}], columnsLabel: [{
|
|
1947
2460
|
type: Input
|
|
1948
2461
|
}], previousLabel: [{
|
|
1949
2462
|
type: Input
|
|
@@ -1951,6 +2464,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1951
2464
|
type: Input
|
|
1952
2465
|
}], emptyLabel: [{
|
|
1953
2466
|
type: Input
|
|
2467
|
+
}], rowsSelectedLabel: [{
|
|
2468
|
+
type: Input
|
|
2469
|
+
}], statusLabel: [{
|
|
2470
|
+
type: Input
|
|
2471
|
+
}], emailLabel: [{
|
|
2472
|
+
type: Input
|
|
2473
|
+
}], amountLabel: [{
|
|
2474
|
+
type: Input
|
|
1954
2475
|
}], rows: [{
|
|
1955
2476
|
type: Input
|
|
1956
2477
|
}], page: [{
|
|
@@ -1959,6 +2480,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1959
2480
|
type: Input
|
|
1960
2481
|
}], query: [{
|
|
1961
2482
|
type: Input
|
|
2483
|
+
}], filterFn: [{
|
|
2484
|
+
type: Input
|
|
1962
2485
|
}], queryChange: [{
|
|
1963
2486
|
type: Output
|
|
1964
2487
|
}], rowAction: [{
|
|
@@ -1967,6 +2490,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1967
2490
|
type: Output
|
|
1968
2491
|
}], selectionChange: [{
|
|
1969
2492
|
type: Output
|
|
2493
|
+
}], columnSort: [{
|
|
2494
|
+
type: Output
|
|
1970
2495
|
}] } });
|
|
1971
2496
|
|
|
1972
2497
|
/**
|
|
@@ -2382,30 +2907,152 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2382
2907
|
args: ['document:keydown.escape']
|
|
2383
2908
|
}] } });
|
|
2384
2909
|
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2910
|
+
/**
|
|
2911
|
+
* Z-Index Scale - Sistema centralizado de z-index
|
|
2912
|
+
*
|
|
2913
|
+
* JERARQUÍA (de menor a mayor):
|
|
2914
|
+
* 1. base (z-0) - Elementos normales del DOM
|
|
2915
|
+
* 2. dropdown (z-10) - Selects, combobox, date-pickers
|
|
2916
|
+
* 3. sticky (z-20) - Headers, navigation bars
|
|
2917
|
+
* 4. overlay (z-30) - Popovers, hover cards, context menus
|
|
2918
|
+
* 5. drawer (z-40) - Sidebar drawer, sheets laterales
|
|
2919
|
+
* 6. modal (z-50) - Dialogs, alert-dialogs
|
|
2920
|
+
* 7. modal-backdrop (z-40) - Backdrop de modals
|
|
2921
|
+
* 8. popover (z-60) - Tooltips, dropdowns DENTRO de modals
|
|
2922
|
+
* 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO
|
|
2923
|
+
*
|
|
2924
|
+
* REGLA CRÍTICA:
|
|
2925
|
+
* - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-60 o mayor
|
|
2926
|
+
* - Esto permite que funcionen DENTRO de modals (z-50)
|
|
2927
|
+
* - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)
|
|
2928
|
+
*/
|
|
2929
|
+
const Z_INDEX = {
|
|
2930
|
+
/**
|
|
2931
|
+
* Base - contenido normal del DOM
|
|
2932
|
+
*/
|
|
2933
|
+
base: 'z-0',
|
|
2934
|
+
/**
|
|
2935
|
+
* Dropdown - Selects, combobox, date-pickers
|
|
2936
|
+
* Debe estar SOBRE contenido normal pero BAJO modals
|
|
2937
|
+
*/
|
|
2938
|
+
dropdown: 'z-10',
|
|
2939
|
+
/**
|
|
2940
|
+
* Sticky - Headers, navigation fija
|
|
2941
|
+
*/
|
|
2942
|
+
sticky: 'z-20',
|
|
2943
|
+
/**
|
|
2944
|
+
* Overlay - Popovers, hover cards, context menus
|
|
2945
|
+
* Debe estar SOBRE sticky pero BAJO modals
|
|
2946
|
+
*/
|
|
2947
|
+
overlay: 'z-30',
|
|
2948
|
+
/**
|
|
2949
|
+
* Drawer backdrop - Backdrop de sidebar drawer
|
|
2950
|
+
* Debe estar DEBAJO del drawer panel
|
|
2951
|
+
*/
|
|
2952
|
+
drawerBackdrop: 'z-40',
|
|
2953
|
+
/**
|
|
2954
|
+
* Drawer - Sidebar drawer, sheets laterales
|
|
2955
|
+
* Debe estar SOBRE su backdrop pero BAJO modals
|
|
2956
|
+
*/
|
|
2957
|
+
drawer: 'z-50',
|
|
2958
|
+
/**
|
|
2959
|
+
* Modal backdrop - Backdrop de dialogs
|
|
2960
|
+
* Debe estar SOBRE drawers pero DEBAJO del contenido del modal
|
|
2961
|
+
*/
|
|
2962
|
+
modalBackdrop: 'z-50',
|
|
2963
|
+
/**
|
|
2964
|
+
* Modal - Dialogs, alert-dialogs, sheets
|
|
2965
|
+
* Debe estar SOBRE su backdrop
|
|
2966
|
+
*/
|
|
2967
|
+
modal: 'z-[60]',
|
|
2968
|
+
/**
|
|
2969
|
+
* Popover - Tooltips, dropdowns, selects options DENTRO de modals
|
|
2970
|
+
* CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals
|
|
2971
|
+
*/
|
|
2972
|
+
popover: 'z-[70]',
|
|
2973
|
+
/**
|
|
2974
|
+
* Toast - Notificaciones globales
|
|
2975
|
+
* Debe estar sobre TODO
|
|
2976
|
+
*/
|
|
2977
|
+
toast: 'z-[100]'
|
|
2978
|
+
};
|
|
2979
|
+
/**
|
|
2980
|
+
* Helper para debugging z-index issues
|
|
2981
|
+
*/
|
|
2982
|
+
function logZIndexStack(element) {
|
|
2983
|
+
if (typeof window === 'undefined')
|
|
2984
|
+
return;
|
|
2985
|
+
let current = element;
|
|
2986
|
+
const stack = [];
|
|
2987
|
+
while (current && current !== document.body) {
|
|
2988
|
+
const computed = window.getComputedStyle(current);
|
|
2989
|
+
const zIndex = computed.zIndex;
|
|
2990
|
+
const position = computed.position;
|
|
2991
|
+
if (zIndex !== 'auto') {
|
|
2992
|
+
stack.push({
|
|
2993
|
+
element: current.tagName + (current.className ? `.${current.className.split(' ')[0]}` : ''),
|
|
2994
|
+
zIndex,
|
|
2995
|
+
position
|
|
2996
|
+
});
|
|
2997
|
+
}
|
|
2998
|
+
current = current.parentElement;
|
|
2999
|
+
}
|
|
3000
|
+
console.table(stack);
|
|
3001
|
+
}
|
|
3002
|
+
|
|
3003
|
+
/**
|
|
3004
|
+
* Modal/Dialog component con soporte responsive
|
|
3005
|
+
*
|
|
3006
|
+
* MEJORADO en v0.2.0:
|
|
3007
|
+
* - Modo 'responsive' (default): fullscreen en mobile, modal en desktop
|
|
3008
|
+
* - Tamaños predefinidos: sm, md, lg, xl
|
|
3009
|
+
* - Mejor manejo de scroll en mobile
|
|
3010
|
+
*
|
|
3011
|
+
* @example
|
|
3012
|
+
* // Responsive (recomendado)
|
|
3013
|
+
* <pdm-dialog [open]="isOpen" size="responsive">
|
|
3014
|
+
* <p>Content</p>
|
|
3015
|
+
* </pdm-dialog>
|
|
3016
|
+
*
|
|
3017
|
+
* @example
|
|
3018
|
+
* // Tamaño fijo
|
|
3019
|
+
* <pdm-dialog [open]="isOpen" size="lg">
|
|
3020
|
+
* <p>Content</p>
|
|
3021
|
+
* </pdm-dialog>
|
|
3022
|
+
*/
|
|
3023
|
+
class PdmDialogComponent {
|
|
3024
|
+
constructor() {
|
|
3025
|
+
this.open = false;
|
|
3026
|
+
this.variant = 'default';
|
|
3027
|
+
/**
|
|
3028
|
+
* Tamaño del dialog
|
|
3029
|
+
* - responsive: fullscreen mobile, modal desktop (recomendado)
|
|
3030
|
+
* - sm: 400px max
|
|
3031
|
+
* - md: 500px max
|
|
3032
|
+
* - lg: 640px max (default)
|
|
3033
|
+
* - xl: 800px max
|
|
3034
|
+
* - desktop/mobile/mobile-fullscreen: legacy, deprecado
|
|
3035
|
+
*/
|
|
3036
|
+
this.size = 'responsive';
|
|
3037
|
+
this.title = 'Edit profile';
|
|
3038
|
+
this.description = '';
|
|
3039
|
+
this.closeOnBackdrop = true;
|
|
3040
|
+
this.closeOnEsc = true;
|
|
3041
|
+
this.showCloseButton = true;
|
|
3042
|
+
this.showHeader = true;
|
|
3043
|
+
this.showFooter = true;
|
|
3044
|
+
this.primaryActionText = 'Save changes';
|
|
3045
|
+
this.secondaryActionText = 'Cancel';
|
|
3046
|
+
this.alignFooter = 'right';
|
|
3047
|
+
this.headerClassName = '';
|
|
3048
|
+
this.bodyClassName = '';
|
|
3049
|
+
this.footerClassName = '';
|
|
3050
|
+
this.className = '';
|
|
3051
|
+
this.openChange = new EventEmitter();
|
|
3052
|
+
this.primaryAction = new EventEmitter();
|
|
3053
|
+
this.secondaryAction = new EventEmitter();
|
|
3054
|
+
}
|
|
3055
|
+
onEsc() {
|
|
2409
3056
|
if (this.open && this.closeOnEsc) {
|
|
2410
3057
|
this.close();
|
|
2411
3058
|
}
|
|
@@ -2425,47 +3072,132 @@ class PdmDialogComponent {
|
|
|
2425
3072
|
}
|
|
2426
3073
|
}
|
|
2427
3074
|
get panelClassName() {
|
|
3075
|
+
// Legacy sizes (backward compatibility)
|
|
3076
|
+
if (this.size === 'desktop') {
|
|
3077
|
+
return this.buildClasses(['max-w-[640px]', 'max-h-[calc(100vh-2rem)]', 'rounded-[10px]']);
|
|
3078
|
+
}
|
|
3079
|
+
if (this.size === 'mobile') {
|
|
3080
|
+
return this.buildClasses(['max-w-[320px]', 'min-h-[240px]', 'rounded-[10px]']);
|
|
3081
|
+
}
|
|
3082
|
+
if (this.size === 'mobile-fullscreen') {
|
|
3083
|
+
return this.buildClasses(['max-w-[320px]', 'h-[min(100dvh,640px)]', 'rounded-none', 'sm:rounded-[10px]']);
|
|
3084
|
+
}
|
|
3085
|
+
// New responsive mode (recomendado)
|
|
3086
|
+
if (this.size === 'responsive') {
|
|
3087
|
+
return this.buildClasses([
|
|
3088
|
+
// Mobile: fullscreen con bordes redondeados solo arriba
|
|
3089
|
+
'w-full',
|
|
3090
|
+
'h-full',
|
|
3091
|
+
'max-h-[100dvh]',
|
|
3092
|
+
'rounded-t-[10px]',
|
|
3093
|
+
'sm:rounded-[10px]',
|
|
3094
|
+
// Desktop: modal centrado
|
|
3095
|
+
'sm:w-auto',
|
|
3096
|
+
'sm:h-auto',
|
|
3097
|
+
'sm:max-w-[640px]',
|
|
3098
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3099
|
+
]);
|
|
3100
|
+
}
|
|
3101
|
+
// New size options
|
|
3102
|
+
const sizeMap = {
|
|
3103
|
+
sm: 'sm:max-w-[400px]',
|
|
3104
|
+
md: 'sm:max-w-[500px]',
|
|
3105
|
+
lg: 'sm:max-w-[640px]',
|
|
3106
|
+
xl: 'sm:max-w-[800px]'
|
|
3107
|
+
};
|
|
3108
|
+
const maxWidth = sizeMap[this.size] || sizeMap.lg;
|
|
3109
|
+
return this.buildClasses([
|
|
3110
|
+
// Mobile: fullscreen
|
|
3111
|
+
'w-full',
|
|
3112
|
+
'h-full',
|
|
3113
|
+
'max-h-[100dvh]',
|
|
3114
|
+
'rounded-t-[10px]',
|
|
3115
|
+
// Desktop: modal
|
|
3116
|
+
'sm:rounded-[10px]',
|
|
3117
|
+
'sm:w-auto',
|
|
3118
|
+
'sm:h-auto',
|
|
3119
|
+
maxWidth,
|
|
3120
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3121
|
+
]);
|
|
3122
|
+
}
|
|
3123
|
+
buildClasses(sizeClasses) {
|
|
2428
3124
|
const base = [
|
|
2429
|
-
'relative
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
3125
|
+
'relative',
|
|
3126
|
+
Z_INDEX.modal,
|
|
3127
|
+
'flex',
|
|
3128
|
+
'flex-col',
|
|
3129
|
+
'border',
|
|
3130
|
+
'border-border',
|
|
3131
|
+
'bg-background',
|
|
3132
|
+
'text-foreground',
|
|
3133
|
+
'shadow-lg',
|
|
3134
|
+
'overflow-hidden',
|
|
3135
|
+
...sizeClasses,
|
|
2435
3136
|
this.className
|
|
2436
3137
|
];
|
|
2437
3138
|
return base.filter(Boolean).join(' ');
|
|
2438
3139
|
}
|
|
2439
3140
|
get bodyWrapperClassName() {
|
|
2440
3141
|
const base = [
|
|
2441
|
-
'
|
|
2442
|
-
|
|
3142
|
+
'flex-1',
|
|
3143
|
+
'overflow-y-auto',
|
|
3144
|
+
'px-4',
|
|
3145
|
+
'py-6',
|
|
3146
|
+
'sm:px-6',
|
|
2443
3147
|
this.bodyClassName
|
|
2444
3148
|
];
|
|
2445
3149
|
return base.filter(Boolean).join(' ');
|
|
2446
3150
|
}
|
|
2447
3151
|
get headerWrapperClassName() {
|
|
2448
|
-
|
|
3152
|
+
const base = [
|
|
3153
|
+
'flex',
|
|
3154
|
+
'items-start',
|
|
3155
|
+
'justify-between',
|
|
3156
|
+
'gap-3',
|
|
3157
|
+
'p-4',
|
|
3158
|
+
'sm:p-6',
|
|
3159
|
+
'border-b',
|
|
3160
|
+
'border-border',
|
|
3161
|
+
this.headerClassName
|
|
3162
|
+
];
|
|
3163
|
+
return base.filter(Boolean).join(' ');
|
|
2449
3164
|
}
|
|
2450
3165
|
get footerWrapperClassName() {
|
|
2451
3166
|
const effectiveAlign = this.alignFooter === 'right' && this.variant === 'custom-close' ? 'left' : this.alignFooter;
|
|
2452
3167
|
const base = [
|
|
2453
3168
|
'p-4',
|
|
3169
|
+
'sm:p-6',
|
|
3170
|
+
'border-t',
|
|
3171
|
+
'border-border',
|
|
3172
|
+
// Mobile: siempre full-width
|
|
3173
|
+
'flex',
|
|
3174
|
+
'flex-col',
|
|
3175
|
+
'gap-2',
|
|
3176
|
+
// Desktop: según alignFooter
|
|
2454
3177
|
effectiveAlign === 'full-width'
|
|
2455
|
-
? 'flex
|
|
2456
|
-
:
|
|
2457
|
-
|
|
2458
|
-
|
|
3178
|
+
? 'sm:flex-col'
|
|
3179
|
+
: 'sm:flex-row sm:items-center',
|
|
3180
|
+
effectiveAlign === 'left' ? 'sm:justify-start' : '',
|
|
3181
|
+
effectiveAlign === 'right' ? 'sm:justify-end' : '',
|
|
2459
3182
|
this.footerClassName
|
|
2460
3183
|
];
|
|
2461
3184
|
return base.filter(Boolean).join(' ');
|
|
2462
3185
|
}
|
|
3186
|
+
get containerClassName() {
|
|
3187
|
+
// Container con backdrop z-50
|
|
3188
|
+
// Mobile: fullscreen desde el bottom
|
|
3189
|
+
// Desktop: centrado
|
|
3190
|
+
return responsive({
|
|
3191
|
+
default: `fixed inset-x-0 bottom-0 ${Z_INDEX.modalBackdrop} flex items-end justify-center`,
|
|
3192
|
+
sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`
|
|
3193
|
+
});
|
|
3194
|
+
}
|
|
2463
3195
|
}
|
|
2464
3196
|
PdmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2465
|
-
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\"
|
|
3197
|
+
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 });
|
|
2466
3198
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, decorators: [{
|
|
2467
3199
|
type: Component,
|
|
2468
|
-
args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3200
|
+
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" }]
|
|
2469
3201
|
}], propDecorators: { open: [{
|
|
2470
3202
|
type: Input
|
|
2471
3203
|
}], variant: [{
|
|
@@ -2511,6 +3243,304 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2511
3243
|
args: ['document:keydown.escape']
|
|
2512
3244
|
}] } });
|
|
2513
3245
|
|
|
3246
|
+
/**
|
|
3247
|
+
* Tabla con funcionalidad de reordenamiento de filas mediante drag & drop
|
|
3248
|
+
*
|
|
3249
|
+
* Extiende pdm-table agregando la capacidad de reordenar filas.
|
|
3250
|
+
* Si no necesitás drag & drop, usá pdm-table directamente (más simple y liviano).
|
|
3251
|
+
*
|
|
3252
|
+
* @example
|
|
3253
|
+
* <pdm-draggable-table
|
|
3254
|
+
* variant="interactive"
|
|
3255
|
+
* [reorderRows]="true"
|
|
3256
|
+
* (rowOrderChange)="onOrderChange($event)">
|
|
3257
|
+
* <tbody>
|
|
3258
|
+
* <tr data-row-id="1"><td>Row 1</td></tr>
|
|
3259
|
+
* <tr data-row-id="2"><td>Row 2</td></tr>
|
|
3260
|
+
* </tbody>
|
|
3261
|
+
* </pdm-draggable-table>
|
|
3262
|
+
*
|
|
3263
|
+
* IMPORTANTE: Cada <tr> debe tener un atributo data-row-id único
|
|
3264
|
+
*/
|
|
3265
|
+
class PdmDraggableTableComponent {
|
|
3266
|
+
constructor(renderer) {
|
|
3267
|
+
this.renderer = renderer;
|
|
3268
|
+
this.variant = 'default';
|
|
3269
|
+
this.responsiveStrategy = 'scroll';
|
|
3270
|
+
this.className = '';
|
|
3271
|
+
this.fullBleed = false;
|
|
3272
|
+
/**
|
|
3273
|
+
* Habilita el reordenamiento de filas mediante drag & drop
|
|
3274
|
+
*/
|
|
3275
|
+
this.reorderRows = false;
|
|
3276
|
+
/**
|
|
3277
|
+
* Selector CSS para identificar los handles de drag
|
|
3278
|
+
* Por defecto busca: [data-drag-handle], [data-slot=row-drag-handle], .row-drag-handle
|
|
3279
|
+
* Si no encuentra ninguno, inserta un handle automático
|
|
3280
|
+
*/
|
|
3281
|
+
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
3282
|
+
/**
|
|
3283
|
+
* Emite el nuevo orden de las filas cuando el usuario termina de arrastrar
|
|
3284
|
+
* Array de data-row-id en el nuevo orden
|
|
3285
|
+
*/
|
|
3286
|
+
this.rowOrderChange = new EventEmitter();
|
|
3287
|
+
this.cleanupListeners = [];
|
|
3288
|
+
this.draggedRow = null;
|
|
3289
|
+
}
|
|
3290
|
+
ngAfterViewInit() {
|
|
3291
|
+
this.syncReorderBehavior();
|
|
3292
|
+
}
|
|
3293
|
+
// Getters para clases CSS (mismo comportamiento que pdm-table)
|
|
3294
|
+
get wrapperClasses() {
|
|
3295
|
+
const baseClasses = ['relative', 'w-full'];
|
|
3296
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
3297
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
3298
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
3299
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
3300
|
+
}
|
|
3301
|
+
return [
|
|
3302
|
+
...baseClasses,
|
|
3303
|
+
...strategyClasses,
|
|
3304
|
+
...variantClasses,
|
|
3305
|
+
this.className
|
|
3306
|
+
].filter(Boolean);
|
|
3307
|
+
}
|
|
3308
|
+
get tableClasses() {
|
|
3309
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
3310
|
+
const variantClasses = this.getVariantTableClasses();
|
|
3311
|
+
const cellClasses = this.getCellClasses();
|
|
3312
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
3313
|
+
}
|
|
3314
|
+
getResponsiveStrategyClasses() {
|
|
3315
|
+
if (this.responsiveStrategy === 'scroll' || this.responsiveStrategy === 'wrap' || this.responsiveStrategy === 'collapse') {
|
|
3316
|
+
return ['overflow-x-auto'];
|
|
3317
|
+
}
|
|
3318
|
+
return [];
|
|
3319
|
+
}
|
|
3320
|
+
getVariantWrapperClasses() {
|
|
3321
|
+
if (this.variant === 'interactive') {
|
|
3322
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
3323
|
+
}
|
|
3324
|
+
if (this.variant === 'data') {
|
|
3325
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
3326
|
+
}
|
|
3327
|
+
return [];
|
|
3328
|
+
}
|
|
3329
|
+
getVariantTableClasses() {
|
|
3330
|
+
if (this.variant === 'data') {
|
|
3331
|
+
return [
|
|
3332
|
+
'border-collapse', 'text-foreground',
|
|
3333
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3334
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3335
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3336
|
+
'[&_th]:h-10', '[&_th]:px-2', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:font-medium',
|
|
3337
|
+
'[&_td]:p-2', '[&_td]:align-middle'
|
|
3338
|
+
];
|
|
3339
|
+
}
|
|
3340
|
+
if (this.variant === 'interactive') {
|
|
3341
|
+
return [
|
|
3342
|
+
'text-foreground',
|
|
3343
|
+
'[&_thead]:sticky', '[&_thead]:top-0', '[&_thead]:z-10', '[&_thead]:bg-muted/70',
|
|
3344
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3345
|
+
'[&_th]:h-12', '[&_th]:px-4', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:text-sm', '[&_th]:font-medium',
|
|
3346
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3347
|
+
'[&_tbody_tr]:transition-colors', '[&_tbody_tr:hover]:bg-muted/50',
|
|
3348
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3349
|
+
'[&_td]:h-14', '[&_td]:px-4', '[&_td]:align-middle', '[&_td]:text-sm',
|
|
3350
|
+
'[&_svg]:text-muted-foreground'
|
|
3351
|
+
];
|
|
3352
|
+
}
|
|
3353
|
+
return [];
|
|
3354
|
+
}
|
|
3355
|
+
getCellClasses() {
|
|
3356
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
3357
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
3358
|
+
}
|
|
3359
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
3360
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
3361
|
+
}
|
|
3362
|
+
return [];
|
|
3363
|
+
}
|
|
3364
|
+
ngOnChanges(changes) {
|
|
3365
|
+
if (changes['reorderRows'] || changes['variant']) {
|
|
3366
|
+
this.syncReorderBehavior();
|
|
3367
|
+
}
|
|
3368
|
+
}
|
|
3369
|
+
ngOnDestroy() {
|
|
3370
|
+
this.cleanupReorderBehavior();
|
|
3371
|
+
}
|
|
3372
|
+
syncReorderBehavior() {
|
|
3373
|
+
this.cleanupReorderBehavior();
|
|
3374
|
+
if (!this.reorderRows) {
|
|
3375
|
+
return;
|
|
3376
|
+
}
|
|
3377
|
+
const tbody = this.getTbody();
|
|
3378
|
+
if (!tbody) {
|
|
3379
|
+
return;
|
|
3380
|
+
}
|
|
3381
|
+
this.setRowsDraggable(tbody, true);
|
|
3382
|
+
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()));
|
|
3383
|
+
// Observer para detectar cambios en el DOM (filas agregadas/removidas)
|
|
3384
|
+
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
3385
|
+
this.observer.observe(tbody, { childList: true });
|
|
3386
|
+
}
|
|
3387
|
+
cleanupReorderBehavior() {
|
|
3388
|
+
this.cleanupListeners.forEach((dispose) => dispose());
|
|
3389
|
+
this.cleanupListeners = [];
|
|
3390
|
+
if (this.observer) {
|
|
3391
|
+
this.observer.disconnect();
|
|
3392
|
+
this.observer = undefined;
|
|
3393
|
+
}
|
|
3394
|
+
const tbody = this.getTbody();
|
|
3395
|
+
if (tbody) {
|
|
3396
|
+
this.setRowsDraggable(tbody, false);
|
|
3397
|
+
}
|
|
3398
|
+
this.draggedRow = null;
|
|
3399
|
+
}
|
|
3400
|
+
getTbody() {
|
|
3401
|
+
var _a, _b;
|
|
3402
|
+
return (_b = (_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.nativeElement.tBodies.item(0)) !== null && _b !== void 0 ? _b : null;
|
|
3403
|
+
}
|
|
3404
|
+
setRowsDraggable(tbody, enabled) {
|
|
3405
|
+
const rows = Array.from(tbody.rows);
|
|
3406
|
+
rows.forEach((row) => {
|
|
3407
|
+
this.syncAutoDragHandle(row, enabled);
|
|
3408
|
+
row.draggable = false;
|
|
3409
|
+
if (!enabled) {
|
|
3410
|
+
delete row.dataset['dragging'];
|
|
3411
|
+
delete row.dataset['dragArmed'];
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
}
|
|
3415
|
+
/**
|
|
3416
|
+
* Inserta un handle de drag automático si no existe uno custom
|
|
3417
|
+
*/
|
|
3418
|
+
syncAutoDragHandle(row, enabled) {
|
|
3419
|
+
const firstCell = row.cells.item(0);
|
|
3420
|
+
if (!firstCell) {
|
|
3421
|
+
return;
|
|
3422
|
+
}
|
|
3423
|
+
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
3424
|
+
if (!enabled) {
|
|
3425
|
+
existingAutoHandle === null || existingAutoHandle === void 0 ? void 0 : existingAutoHandle.remove();
|
|
3426
|
+
return;
|
|
3427
|
+
}
|
|
3428
|
+
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
3429
|
+
if (hasCustomHandle || existingAutoHandle) {
|
|
3430
|
+
return;
|
|
3431
|
+
}
|
|
3432
|
+
// Crear handle automático
|
|
3433
|
+
const button = this.renderer.createElement('button');
|
|
3434
|
+
this.renderer.setAttribute(button, 'type', 'button');
|
|
3435
|
+
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
3436
|
+
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
3437
|
+
this.renderer.addClass(button, 'inline-flex');
|
|
3438
|
+
this.renderer.addClass(button, 'h-7');
|
|
3439
|
+
this.renderer.addClass(button, 'w-7');
|
|
3440
|
+
this.renderer.addClass(button, 'items-center');
|
|
3441
|
+
this.renderer.addClass(button, 'justify-center');
|
|
3442
|
+
this.renderer.addClass(button, 'cursor-grab');
|
|
3443
|
+
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
3444
|
+
this.renderer.addClass(button, 'text-muted-foreground');
|
|
3445
|
+
const dots = this.renderer.createElement('span');
|
|
3446
|
+
this.renderer.addClass(dots, 'text-sm');
|
|
3447
|
+
this.renderer.addClass(dots, 'leading-none');
|
|
3448
|
+
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
3449
|
+
this.renderer.appendChild(button, dots);
|
|
3450
|
+
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
3451
|
+
}
|
|
3452
|
+
onDragStart(event) {
|
|
3453
|
+
const target = event.target;
|
|
3454
|
+
const row = target === null || target === void 0 ? void 0 : target.closest('tr');
|
|
3455
|
+
if (!row) {
|
|
3456
|
+
return;
|
|
3457
|
+
}
|
|
3458
|
+
const handle = target === null || target === void 0 ? void 0 : target.closest(this.dragHandleSelector);
|
|
3459
|
+
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
3460
|
+
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
3461
|
+
event.preventDefault();
|
|
3462
|
+
return;
|
|
3463
|
+
}
|
|
3464
|
+
this.draggedRow = row;
|
|
3465
|
+
this.draggedRow.dataset['dragging'] = 'true';
|
|
3466
|
+
if (event.dataTransfer) {
|
|
3467
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
3468
|
+
event.dataTransfer.setData('text/plain', '');
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
onDragOver(event, tbody) {
|
|
3472
|
+
if (!this.draggedRow) {
|
|
3473
|
+
return;
|
|
3474
|
+
}
|
|
3475
|
+
event.preventDefault();
|
|
3476
|
+
const target = event.target;
|
|
3477
|
+
const targetRow = target === null || target === void 0 ? void 0 : target.closest('tr');
|
|
3478
|
+
if (!targetRow || targetRow === this.draggedRow) {
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
const rect = targetRow.getBoundingClientRect();
|
|
3482
|
+
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
3483
|
+
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
3484
|
+
}
|
|
3485
|
+
onDrop(event) {
|
|
3486
|
+
event.preventDefault();
|
|
3487
|
+
}
|
|
3488
|
+
onDragEnd() {
|
|
3489
|
+
const tbody = this.getTbody();
|
|
3490
|
+
if (tbody) {
|
|
3491
|
+
Array.from(tbody.rows).forEach((row) => {
|
|
3492
|
+
row.draggable = false;
|
|
3493
|
+
delete row.dataset['dragArmed'];
|
|
3494
|
+
});
|
|
3495
|
+
}
|
|
3496
|
+
if (this.draggedRow) {
|
|
3497
|
+
delete this.draggedRow.dataset['dragging'];
|
|
3498
|
+
this.draggedRow = null;
|
|
3499
|
+
}
|
|
3500
|
+
if (!tbody) {
|
|
3501
|
+
return;
|
|
3502
|
+
}
|
|
3503
|
+
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
3504
|
+
this.rowOrderChange.emit(order);
|
|
3505
|
+
}
|
|
3506
|
+
armDragFromHandle(event) {
|
|
3507
|
+
const target = event.target;
|
|
3508
|
+
const handle = target === null || target === void 0 ? void 0 : target.closest(this.dragHandleSelector);
|
|
3509
|
+
if (!handle) {
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3512
|
+
const row = handle.closest('tr');
|
|
3513
|
+
if (!row) {
|
|
3514
|
+
return;
|
|
3515
|
+
}
|
|
3516
|
+
row.draggable = true;
|
|
3517
|
+
row.dataset['dragArmed'] = 'true';
|
|
3518
|
+
}
|
|
3519
|
+
}
|
|
3520
|
+
PdmDraggableTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
3521
|
+
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 });
|
|
3522
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, decorators: [{
|
|
3523
|
+
type: Component,
|
|
3524
|
+
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" }]
|
|
3525
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
3526
|
+
type: Input
|
|
3527
|
+
}], responsiveStrategy: [{
|
|
3528
|
+
type: Input
|
|
3529
|
+
}], className: [{
|
|
3530
|
+
type: Input
|
|
3531
|
+
}], fullBleed: [{
|
|
3532
|
+
type: Input
|
|
3533
|
+
}], reorderRows: [{
|
|
3534
|
+
type: Input
|
|
3535
|
+
}], dragHandleSelector: [{
|
|
3536
|
+
type: Input
|
|
3537
|
+
}], rowOrderChange: [{
|
|
3538
|
+
type: Output
|
|
3539
|
+
}], tableElement: [{
|
|
3540
|
+
type: ViewChild,
|
|
3541
|
+
args: ['tableElement']
|
|
3542
|
+
}] } });
|
|
3543
|
+
|
|
2514
3544
|
class PdmDropdownMenuComponent {
|
|
2515
3545
|
constructor(elementRef, cdr, overlay, viewContainerRef) {
|
|
2516
3546
|
this.elementRef = elementRef;
|
|
@@ -2624,7 +3654,7 @@ class PdmDropdownMenuComponent {
|
|
|
2624
3654
|
this.cdr.markForCheck();
|
|
2625
3655
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 8);
|
|
2626
3656
|
// Resolve panelClass: overlayOptions.panelClass wins; otherwise map panelClassName.
|
|
2627
|
-
const resolvedPanelClass = (_c = (_b = this.overlayOptions) === null || _b === void 0 ? void 0 : _b.panelClass) !== null && _c !== void 0 ? _c : (this.panelClassName ? [
|
|
3657
|
+
const resolvedPanelClass = (_c = (_b = this.overlayOptions) === null || _b === void 0 ? void 0 : _b.panelClass) !== null && _c !== void 0 ? _c : (this.panelClassName ? [Z_INDEX.popover, this.panelClassName] : [Z_INDEX.popover]);
|
|
2628
3658
|
this.overlayRef = this.overlay.create(Object.assign(Object.assign({ positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition() }, this.overlayOptions), {
|
|
2629
3659
|
// panelClass always overrides last: it already merges panelClassName + overlayOptions.
|
|
2630
3660
|
panelClass: resolvedPanelClass }));
|
|
@@ -2690,13 +3720,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2690
3720
|
args: ['document:keydown.escape']
|
|
2691
3721
|
}] } });
|
|
2692
3722
|
|
|
3723
|
+
/**
|
|
3724
|
+
* Drawer/Sheet component con soporte responsive
|
|
3725
|
+
*
|
|
3726
|
+
* MEJORADO en v0.2.0:
|
|
3727
|
+
* - Posicionamiento configurable (bottom, left, right, top)
|
|
3728
|
+
* - Tamaños predefinidos
|
|
3729
|
+
* - Responsive: bottom sheet en mobile, side panel en desktop
|
|
3730
|
+
* - Contenido genérico via ng-content
|
|
3731
|
+
*
|
|
3732
|
+
* @example
|
|
3733
|
+
* // Drawer simple desde el bottom
|
|
3734
|
+
* <pdm-drawer [open]="isOpen" position="bottom">
|
|
3735
|
+
* <h3>Title</h3>
|
|
3736
|
+
* <p>Content</p>
|
|
3737
|
+
* </pdm-drawer>
|
|
3738
|
+
*
|
|
3739
|
+
* @example
|
|
3740
|
+
* // Side panel desde la right
|
|
3741
|
+
* <pdm-drawer [open]="isOpen" position="right" size="md">
|
|
3742
|
+
* <p>Content</p>
|
|
3743
|
+
* </pdm-drawer>
|
|
3744
|
+
*/
|
|
2693
3745
|
class PdmDrawerComponent {
|
|
2694
3746
|
constructor() {
|
|
2695
3747
|
this.open = false;
|
|
3748
|
+
/**
|
|
3749
|
+
* Posición del drawer
|
|
3750
|
+
* - bottom: desde abajo (default, mejor para mobile)
|
|
3751
|
+
* - left: side panel desde izquierda
|
|
3752
|
+
* - right: side panel desde derecha
|
|
3753
|
+
* - top: desde arriba (poco común)
|
|
3754
|
+
*/
|
|
3755
|
+
this.position = 'bottom';
|
|
3756
|
+
/**
|
|
3757
|
+
* Tamaño del drawer
|
|
3758
|
+
* - sm: 400px (side) / 50vh (bottom/top)
|
|
3759
|
+
* - md: 500px (side) / 66vh (bottom/top) (default)
|
|
3760
|
+
* - lg: 640px (side) / 80vh (bottom/top)
|
|
3761
|
+
* - full: 100% ancho/alto
|
|
3762
|
+
*/
|
|
3763
|
+
this.size = 'md';
|
|
3764
|
+
/**
|
|
3765
|
+
* @deprecated Use position="bottom" instead
|
|
3766
|
+
*/
|
|
2696
3767
|
this.variant = 'drawer';
|
|
2697
3768
|
this.className = '';
|
|
2698
3769
|
this.title = '';
|
|
2699
3770
|
this.description = '';
|
|
3771
|
+
/**
|
|
3772
|
+
* Mostrar handle visual (línea para arrastrar)
|
|
3773
|
+
* Solo tiene sentido en position="bottom"
|
|
3774
|
+
*/
|
|
3775
|
+
this.showHandle = true;
|
|
3776
|
+
/**
|
|
3777
|
+
* Mostrar botón de cerrar
|
|
3778
|
+
*/
|
|
3779
|
+
this.showCloseButton = true;
|
|
3780
|
+
this.closeOnEsc = true;
|
|
3781
|
+
this.closeOnBackdropClick = true;
|
|
3782
|
+
this.openChange = new EventEmitter();
|
|
3783
|
+
// DEPRECATED: contenido específico que se movió a ng-content
|
|
2700
3784
|
this.value = '';
|
|
2701
3785
|
this.unit = '';
|
|
2702
3786
|
this.decrementLabel = '-';
|
|
@@ -2710,14 +3794,9 @@ class PdmDrawerComponent {
|
|
|
2710
3794
|
this.usernameLabel = 'Username';
|
|
2711
3795
|
this.usernameValue = '';
|
|
2712
3796
|
this.responsivePrimaryLabel = '';
|
|
2713
|
-
|
|
2714
|
-
this.closeOnEsc = true;
|
|
2715
|
-
/** Close when the backdrop is clicked. Default: `true`. */
|
|
2716
|
-
this.closeOnBackdropClick = true;
|
|
2717
|
-
this.openChange = new EventEmitter();
|
|
3797
|
+
this.bars = [];
|
|
2718
3798
|
this.primaryAction = new EventEmitter();
|
|
2719
3799
|
this.secondaryAction = new EventEmitter();
|
|
2720
|
-
this.bars = [];
|
|
2721
3800
|
}
|
|
2722
3801
|
onEsc() {
|
|
2723
3802
|
if (this.open && this.closeOnEsc) {
|
|
@@ -2738,14 +3817,67 @@ class PdmDrawerComponent {
|
|
|
2738
3817
|
onSecondaryAction() {
|
|
2739
3818
|
this.secondaryAction.emit();
|
|
2740
3819
|
}
|
|
3820
|
+
get containerClassName() {
|
|
3821
|
+
return `fixed inset-0 ${Z_INDEX.drawer} ${this.className}`;
|
|
3822
|
+
}
|
|
3823
|
+
get panelClassName() {
|
|
3824
|
+
const base = [
|
|
3825
|
+
'absolute',
|
|
3826
|
+
'bg-background',
|
|
3827
|
+
'border',
|
|
3828
|
+
'border-border',
|
|
3829
|
+
'shadow-lg',
|
|
3830
|
+
'overflow-auto'
|
|
3831
|
+
];
|
|
3832
|
+
// Posicionamiento
|
|
3833
|
+
const positionClasses = this.getPositionClasses();
|
|
3834
|
+
// Tamaño
|
|
3835
|
+
const sizeClasses = this.getSizeClasses();
|
|
3836
|
+
return [...base, ...positionClasses, ...sizeClasses].filter(Boolean).join(' ');
|
|
3837
|
+
}
|
|
3838
|
+
getPositionClasses() {
|
|
3839
|
+
const map = {
|
|
3840
|
+
bottom: ['inset-x-0', 'bottom-0', 'rounded-t-xl'],
|
|
3841
|
+
top: ['inset-x-0', 'top-0', 'rounded-b-xl'],
|
|
3842
|
+
left: ['inset-y-0', 'left-0', 'rounded-r-xl'],
|
|
3843
|
+
right: ['inset-y-0', 'right-0', 'rounded-l-xl']
|
|
3844
|
+
};
|
|
3845
|
+
return map[this.position] || map.bottom;
|
|
3846
|
+
}
|
|
3847
|
+
getSizeClasses() {
|
|
3848
|
+
const isVertical = this.position === 'bottom' || this.position === 'top';
|
|
3849
|
+
if (this.size === 'full') {
|
|
3850
|
+
return ['w-full', 'h-full'];
|
|
3851
|
+
}
|
|
3852
|
+
const sizeMap = {
|
|
3853
|
+
sm: isVertical ? 'max-h-[50vh]' : 'max-w-[400px]',
|
|
3854
|
+
md: isVertical ? 'max-h-[66vh]' : 'max-w-[500px]',
|
|
3855
|
+
lg: isVertical ? 'max-h-[80vh]' : 'max-w-[640px]'
|
|
3856
|
+
};
|
|
3857
|
+
const maxDimension = sizeMap[this.size] || sizeMap.md;
|
|
3858
|
+
if (isVertical) {
|
|
3859
|
+
return ['w-full', maxDimension];
|
|
3860
|
+
}
|
|
3861
|
+
else {
|
|
3862
|
+
return ['h-full', maxDimension];
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
get showLegacyContent() {
|
|
3866
|
+
// Mostrar contenido legacy si variant está siendo usado
|
|
3867
|
+
return this.variant === 'drawer' || this.variant === 'responsive-dialog';
|
|
3868
|
+
}
|
|
2741
3869
|
}
|
|
2742
3870
|
PdmDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2743
|
-
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",
|
|
3871
|
+
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 });
|
|
2744
3872
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, decorators: [{
|
|
2745
3873
|
type: Component,
|
|
2746
|
-
args: [{ selector: 'pdm-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3874
|
+
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" }]
|
|
2747
3875
|
}], propDecorators: { open: [{
|
|
2748
3876
|
type: Input
|
|
3877
|
+
}], position: [{
|
|
3878
|
+
type: Input
|
|
3879
|
+
}], size: [{
|
|
3880
|
+
type: Input
|
|
2749
3881
|
}], variant: [{
|
|
2750
3882
|
type: Input
|
|
2751
3883
|
}], className: [{
|
|
@@ -2754,6 +3886,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2754
3886
|
type: Input
|
|
2755
3887
|
}], description: [{
|
|
2756
3888
|
type: Input
|
|
3889
|
+
}], showHandle: [{
|
|
3890
|
+
type: Input
|
|
3891
|
+
}], showCloseButton: [{
|
|
3892
|
+
type: Input
|
|
3893
|
+
}], closeOnEsc: [{
|
|
3894
|
+
type: Input
|
|
3895
|
+
}], closeOnBackdropClick: [{
|
|
3896
|
+
type: Input
|
|
3897
|
+
}], openChange: [{
|
|
3898
|
+
type: Output
|
|
2757
3899
|
}], value: [{
|
|
2758
3900
|
type: Input
|
|
2759
3901
|
}], unit: [{
|
|
@@ -2778,20 +3920,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2778
3920
|
type: Input
|
|
2779
3921
|
}], usernameValue: [{
|
|
2780
3922
|
type: Input
|
|
2781
|
-
}], responsivePrimaryLabel: [{
|
|
2782
|
-
type: Input
|
|
2783
|
-
}], closeOnEsc: [{
|
|
3923
|
+
}], responsivePrimaryLabel: [{
|
|
2784
3924
|
type: Input
|
|
2785
|
-
}],
|
|
3925
|
+
}], bars: [{
|
|
2786
3926
|
type: Input
|
|
2787
|
-
}], openChange: [{
|
|
2788
|
-
type: Output
|
|
2789
3927
|
}], primaryAction: [{
|
|
2790
3928
|
type: Output
|
|
2791
3929
|
}], secondaryAction: [{
|
|
2792
3930
|
type: Output
|
|
2793
|
-
}], bars: [{
|
|
2794
|
-
type: Input
|
|
2795
3931
|
}], onEsc: [{
|
|
2796
3932
|
type: HostListener,
|
|
2797
3933
|
args: ['document:keydown.escape']
|
|
@@ -2936,10 +4072,10 @@ class PdmHoverCardComponent {
|
|
|
2936
4072
|
}
|
|
2937
4073
|
}
|
|
2938
4074
|
PdmHoverCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2939
|
-
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-
|
|
4075
|
+
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 });
|
|
2940
4076
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, decorators: [{
|
|
2941
4077
|
type: Component,
|
|
2942
|
-
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-
|
|
4078
|
+
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" }]
|
|
2943
4079
|
}], propDecorators: { className: [{
|
|
2944
4080
|
type: Input
|
|
2945
4081
|
}], panelClassName: [{
|
|
@@ -3377,10 +4513,10 @@ class PdmMenubarComponent {
|
|
|
3377
4513
|
}
|
|
3378
4514
|
}
|
|
3379
4515
|
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 });
|
|
3380
|
-
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-
|
|
4516
|
+
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 });
|
|
3381
4517
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, decorators: [{
|
|
3382
4518
|
type: Component,
|
|
3383
|
-
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-
|
|
4519
|
+
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" }]
|
|
3384
4520
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
|
|
3385
4521
|
type: Input
|
|
3386
4522
|
}], className: [{
|
|
@@ -3430,21 +4566,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3430
4566
|
type: Output
|
|
3431
4567
|
}] } });
|
|
3432
4568
|
|
|
4569
|
+
/**
|
|
4570
|
+
* Navigation Menu component - Navegación horizontal responsive
|
|
4571
|
+
*
|
|
4572
|
+
* MEJORAS en v0.2.0:
|
|
4573
|
+
* - Modo scroll: overflow-x-auto con scroll indicators en mobile
|
|
4574
|
+
* - Modo compact: items abreviados en mobile, completos en desktop
|
|
4575
|
+
* - Scroll smooth automático al item activo
|
|
4576
|
+
*
|
|
4577
|
+
* @example
|
|
4578
|
+
* <!-- Scroll horizontal (default) -->
|
|
4579
|
+
* <pdm-navigation-menu [items]="navItems"></pdm-navigation-menu>
|
|
4580
|
+
*
|
|
4581
|
+
* <!-- Compact mode -->
|
|
4582
|
+
* <pdm-navigation-menu [items]="navItems" mobileMode="compact"></pdm-navigation-menu>
|
|
4583
|
+
*/
|
|
3433
4584
|
class PdmNavigationMenuComponent {
|
|
3434
4585
|
constructor() {
|
|
3435
4586
|
this.items = [];
|
|
3436
4587
|
this.className = '';
|
|
4588
|
+
/**
|
|
4589
|
+
* Mobile behavior: 'scroll' (horizontal scroll) o 'compact' (items reducidos)
|
|
4590
|
+
* @default 'scroll'
|
|
4591
|
+
*/
|
|
4592
|
+
this.mobileMode = 'scroll';
|
|
3437
4593
|
}
|
|
3438
4594
|
}
|
|
3439
4595
|
PdmNavigationMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3440
|
-
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
|
|
4596
|
+
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 });
|
|
3441
4597
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, decorators: [{
|
|
3442
4598
|
type: Component,
|
|
3443
|
-
args: [{ selector: 'pdm-navigation-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav
|
|
4599
|
+
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" }]
|
|
3444
4600
|
}], propDecorators: { items: [{
|
|
3445
4601
|
type: Input
|
|
3446
4602
|
}], className: [{
|
|
3447
4603
|
type: Input
|
|
4604
|
+
}], mobileMode: [{
|
|
4605
|
+
type: Input
|
|
3448
4606
|
}] } });
|
|
3449
4607
|
|
|
3450
4608
|
/**
|
|
@@ -3667,8 +4825,9 @@ class PdmSelectComponent {
|
|
|
3667
4825
|
this.cdr.markForCheck();
|
|
3668
4826
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 4);
|
|
3669
4827
|
this.overlayRef = this.overlay.create(Object.assign({
|
|
3670
|
-
//
|
|
3671
|
-
panelClass
|
|
4828
|
+
// CRÍTICO: z-[70] para aparecer SOBRE modals (z-[60])
|
|
4829
|
+
// panelClass se aplica al cdk-overlay-pane wrapper
|
|
4830
|
+
panelClass: [Z_INDEX.popover], positionStrategy, scrollStrategy: this.overlay.scrollStrategies.reposition(), width: triggerEl.offsetWidth }, this.overlayOptions));
|
|
3672
4831
|
const portal = new TemplatePortal(this.panelTemplateRef, this.viewContainerRef);
|
|
3673
4832
|
this.overlayRef.attach(portal);
|
|
3674
4833
|
this.backdropSub = this.overlayRef.outsidePointerEvents().subscribe((event) => {
|
|
@@ -3777,10 +4936,10 @@ class PdmPaginationComponent {
|
|
|
3777
4936
|
}
|
|
3778
4937
|
}
|
|
3779
4938
|
PdmPaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3780
|
-
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 });
|
|
4939
|
+
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 });
|
|
3781
4940
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, decorators: [{
|
|
3782
4941
|
type: Component,
|
|
3783
|
-
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" }]
|
|
4942
|
+
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" }]
|
|
3784
4943
|
}], propDecorators: { page: [{
|
|
3785
4944
|
type: Input
|
|
3786
4945
|
}], pageCount: [{
|
|
@@ -3836,10 +4995,11 @@ class PdmPopoverComponent {
|
|
|
3836
4995
|
return this._open;
|
|
3837
4996
|
}
|
|
3838
4997
|
get panelClasses() {
|
|
4998
|
+
const baseClasses = 'min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md';
|
|
3839
4999
|
return [
|
|
3840
5000
|
this.panelPlacement === 'top'
|
|
3841
|
-
?
|
|
3842
|
-
:
|
|
5001
|
+
? `absolute bottom-full left-0 ${Z_INDEX.popover} mb-2 ${baseClasses}`
|
|
5002
|
+
: `absolute left-0 top-full ${Z_INDEX.popover} mt-2 ${baseClasses}`,
|
|
3843
5003
|
this.panelClassName
|
|
3844
5004
|
];
|
|
3845
5005
|
}
|
|
@@ -4032,14 +5192,38 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4032
5192
|
type: Input
|
|
4033
5193
|
}] } });
|
|
4034
5194
|
|
|
5195
|
+
/**
|
|
5196
|
+
* Sheet/Side panel component con soporte responsive
|
|
5197
|
+
*
|
|
5198
|
+
* MEJORADO en v0.2.0:
|
|
5199
|
+
* - Tamaños configurables
|
|
5200
|
+
* - Mejor manejo de overflow
|
|
5201
|
+
* - Responsive sizes
|
|
5202
|
+
*
|
|
5203
|
+
* @example
|
|
5204
|
+
* <pdm-sheet [open]="isOpen" side="right" size="md">
|
|
5205
|
+
* <h3>Settings</h3>
|
|
5206
|
+
* <p>Content here</p>
|
|
5207
|
+
* </pdm-sheet>
|
|
5208
|
+
*/
|
|
4035
5209
|
class PdmSheetComponent {
|
|
4036
5210
|
constructor() {
|
|
4037
5211
|
this.open = false;
|
|
5212
|
+
/**
|
|
5213
|
+
* Lado desde donde aparece el sheet
|
|
5214
|
+
*/
|
|
4038
5215
|
this.side = 'right';
|
|
5216
|
+
/**
|
|
5217
|
+
* Tamaño del sheet
|
|
5218
|
+
* - sm: 320px (side) / 40vh (top/bottom)
|
|
5219
|
+
* - md: 400px (side) / 50vh (top/bottom) (default)
|
|
5220
|
+
* - lg: 500px (side) / 66vh (top/bottom)
|
|
5221
|
+
* - xl: 640px (side) / 80vh (top/bottom)
|
|
5222
|
+
* - full: 100%
|
|
5223
|
+
*/
|
|
5224
|
+
this.size = 'md';
|
|
4039
5225
|
this.className = '';
|
|
4040
|
-
/** Close when the ESC key is pressed. Default: `true`. */
|
|
4041
5226
|
this.closeOnEsc = true;
|
|
4042
|
-
/** Close when the backdrop is clicked. Default: `true`. */
|
|
4043
5227
|
this.closeOnBackdropClick = true;
|
|
4044
5228
|
this.openChange = new EventEmitter();
|
|
4045
5229
|
}
|
|
@@ -4057,24 +5241,56 @@ class PdmSheetComponent {
|
|
|
4057
5241
|
this.openChange.emit(false);
|
|
4058
5242
|
}
|
|
4059
5243
|
get panelClass() {
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
5244
|
+
const base = 'absolute bg-background border-border shadow-lg overflow-auto';
|
|
5245
|
+
const position = this.getPositionClass();
|
|
5246
|
+
const sizing = this.getSizingClass();
|
|
5247
|
+
return `${base} ${position} ${sizing} ${this.className}`.trim();
|
|
5248
|
+
}
|
|
5249
|
+
getPositionClass() {
|
|
5250
|
+
const map = {
|
|
5251
|
+
left: 'left-0 top-0 h-full border-r',
|
|
5252
|
+
right: 'right-0 top-0 h-full border-l',
|
|
5253
|
+
top: 'top-0 left-0 w-full border-b',
|
|
5254
|
+
bottom: 'bottom-0 left-0 w-full border-t'
|
|
5255
|
+
};
|
|
5256
|
+
return map[this.side];
|
|
5257
|
+
}
|
|
5258
|
+
getSizingClass() {
|
|
5259
|
+
if (this.size === 'full') {
|
|
5260
|
+
return 'w-full h-full';
|
|
5261
|
+
}
|
|
5262
|
+
const isHorizontal = this.side === 'left' || this.side === 'right';
|
|
5263
|
+
if (isHorizontal) {
|
|
5264
|
+
const widthMap = {
|
|
5265
|
+
sm: 'w-full max-w-[320px] sm:max-w-[320px]',
|
|
5266
|
+
md: 'w-full max-w-[360px] sm:max-w-[400px]',
|
|
5267
|
+
lg: 'w-full max-w-[400px] sm:max-w-[500px]',
|
|
5268
|
+
xl: 'w-full max-w-[500px] sm:max-w-[640px]'
|
|
5269
|
+
};
|
|
5270
|
+
return widthMap[this.size] || widthMap.md;
|
|
5271
|
+
}
|
|
5272
|
+
else {
|
|
5273
|
+
const heightMap = {
|
|
5274
|
+
sm: 'max-h-[40vh]',
|
|
5275
|
+
md: 'max-h-[50vh]',
|
|
5276
|
+
lg: 'max-h-[66vh]',
|
|
5277
|
+
xl: 'max-h-[80vh]'
|
|
5278
|
+
};
|
|
5279
|
+
return heightMap[this.size] || heightMap.md;
|
|
5280
|
+
}
|
|
4067
5281
|
}
|
|
4068
5282
|
}
|
|
4069
5283
|
PdmSheetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4070
|
-
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 });
|
|
5284
|
+
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 });
|
|
4071
5285
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, decorators: [{
|
|
4072
5286
|
type: Component,
|
|
4073
|
-
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" }]
|
|
5287
|
+
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" }]
|
|
4074
5288
|
}], propDecorators: { open: [{
|
|
4075
5289
|
type: Input
|
|
4076
5290
|
}], side: [{
|
|
4077
5291
|
type: Input
|
|
5292
|
+
}], size: [{
|
|
5293
|
+
type: Input
|
|
4078
5294
|
}], className: [{
|
|
4079
5295
|
type: Input
|
|
4080
5296
|
}], closeOnEsc: [{
|
|
@@ -4088,21 +5304,68 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4088
5304
|
args: ['document:keydown.escape']
|
|
4089
5305
|
}] } });
|
|
4090
5306
|
|
|
5307
|
+
/**
|
|
5308
|
+
* Sidebar component - Navegación lateral responsive
|
|
5309
|
+
*
|
|
5310
|
+
* MEJORAS en v0.2.0:
|
|
5311
|
+
* - Mobile drawer mode: overlay fullscreen en mobile, sidebar fijo en desktop
|
|
5312
|
+
* - Sidebar mode: sidebar persistente con widths responsive
|
|
5313
|
+
* - Backdrop automático en mobile drawer mode
|
|
5314
|
+
*
|
|
5315
|
+
* @example
|
|
5316
|
+
* <!-- Mobile drawer (default) -->
|
|
5317
|
+
* <pdm-sidebar [open]="sidebarOpen" (openChange)="sidebarOpen = $event">
|
|
5318
|
+
* <nav>Menu items...</nav>
|
|
5319
|
+
* </pdm-sidebar>
|
|
5320
|
+
*
|
|
5321
|
+
* <!-- Sidebar persistente -->
|
|
5322
|
+
* <pdm-sidebar mobileMode="sidebar" [collapsed]="collapsed">
|
|
5323
|
+
* <nav>Menu items...</nav>
|
|
5324
|
+
* </pdm-sidebar>
|
|
5325
|
+
*/
|
|
4091
5326
|
class PdmSidebarComponent {
|
|
4092
5327
|
constructor() {
|
|
5328
|
+
/**
|
|
5329
|
+
* Mobile behavior: 'drawer' (overlay) o 'sidebar' (persistente)
|
|
5330
|
+
* @default 'drawer'
|
|
5331
|
+
*/
|
|
5332
|
+
this.mobileMode = 'drawer';
|
|
5333
|
+
/**
|
|
5334
|
+
* Collapsed state (solo aplica en mobileMode="sidebar")
|
|
5335
|
+
*/
|
|
4093
5336
|
this.collapsed = false;
|
|
5337
|
+
/**
|
|
5338
|
+
* Open state (solo aplica en mobileMode="drawer")
|
|
5339
|
+
*/
|
|
5340
|
+
this.open = false;
|
|
4094
5341
|
this.className = '';
|
|
5342
|
+
/**
|
|
5343
|
+
* Emite cuando el drawer se cierra (solo en mobileMode="drawer")
|
|
5344
|
+
*/
|
|
5345
|
+
this.openChange = new EventEmitter();
|
|
5346
|
+
}
|
|
5347
|
+
onBackdropClick() {
|
|
5348
|
+
if (this.mobileMode === 'drawer') {
|
|
5349
|
+
this.open = false;
|
|
5350
|
+
this.openChange.emit(false);
|
|
5351
|
+
}
|
|
4095
5352
|
}
|
|
4096
5353
|
}
|
|
4097
5354
|
PdmSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4098
|
-
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'
|
|
5355
|
+
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 });
|
|
4099
5356
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, decorators: [{
|
|
4100
5357
|
type: Component,
|
|
4101
|
-
args: [{ selector: 'pdm-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<aside [ngClass]=\"['h-full border-r border-border bg-background transition-all'
|
|
4102
|
-
}], propDecorators: {
|
|
5358
|
+
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" }]
|
|
5359
|
+
}], propDecorators: { mobileMode: [{
|
|
5360
|
+
type: Input
|
|
5361
|
+
}], collapsed: [{
|
|
5362
|
+
type: Input
|
|
5363
|
+
}], open: [{
|
|
4103
5364
|
type: Input
|
|
4104
5365
|
}], className: [{
|
|
4105
5366
|
type: Input
|
|
5367
|
+
}], openChange: [{
|
|
5368
|
+
type: Output
|
|
4106
5369
|
}] } });
|
|
4107
5370
|
|
|
4108
5371
|
class PdmSkeletonComponent {
|
|
@@ -4269,213 +5532,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4269
5532
|
type: Output
|
|
4270
5533
|
}] } });
|
|
4271
5534
|
|
|
4272
|
-
class PdmTableComponent {
|
|
4273
|
-
constructor(renderer) {
|
|
4274
|
-
this.renderer = renderer;
|
|
4275
|
-
this.variant = 'default';
|
|
4276
|
-
this.reorderRows = false;
|
|
4277
|
-
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
4278
|
-
this.className = '';
|
|
4279
|
-
this.rowOrderChange = new EventEmitter();
|
|
4280
|
-
this.cleanupListeners = [];
|
|
4281
|
-
this.draggedRow = null;
|
|
4282
|
-
}
|
|
4283
|
-
ngAfterViewInit() {
|
|
4284
|
-
this.syncReorderBehavior();
|
|
4285
|
-
}
|
|
4286
|
-
ngOnChanges(changes) {
|
|
4287
|
-
if (changes['reorderRows'] || changes['variant']) {
|
|
4288
|
-
this.syncReorderBehavior();
|
|
4289
|
-
}
|
|
4290
|
-
}
|
|
4291
|
-
ngOnDestroy() {
|
|
4292
|
-
this.cleanupReorderBehavior();
|
|
4293
|
-
}
|
|
4294
|
-
get wrapperClasses() {
|
|
4295
|
-
return [
|
|
4296
|
-
'relative w-full overflow-auto',
|
|
4297
|
-
this.variant === 'interactive' ? 'overflow-x-auto overflow-y-hidden rounded-xl border border-border bg-background' : '',
|
|
4298
|
-
this.variant === 'data' ? 'overflow-hidden rounded-md border border-border bg-background' : '',
|
|
4299
|
-
this.className
|
|
4300
|
-
];
|
|
4301
|
-
}
|
|
4302
|
-
get tableClasses() {
|
|
4303
|
-
return [
|
|
4304
|
-
'w-full caption-bottom text-sm',
|
|
4305
|
-
this.variant === 'data'
|
|
4306
|
-
? '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'
|
|
4307
|
-
: '',
|
|
4308
|
-
this.variant === 'interactive'
|
|
4309
|
-
? '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'
|
|
4310
|
-
: ''
|
|
4311
|
-
];
|
|
4312
|
-
}
|
|
4313
|
-
syncReorderBehavior() {
|
|
4314
|
-
this.cleanupReorderBehavior();
|
|
4315
|
-
if (!this.isReorderEnabled) {
|
|
4316
|
-
return;
|
|
4317
|
-
}
|
|
4318
|
-
const tbody = this.getTbody();
|
|
4319
|
-
if (!tbody) {
|
|
4320
|
-
return;
|
|
4321
|
-
}
|
|
4322
|
-
this.setRowsDraggable(tbody, true);
|
|
4323
|
-
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()));
|
|
4324
|
-
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
4325
|
-
this.observer.observe(tbody, { childList: true });
|
|
4326
|
-
}
|
|
4327
|
-
cleanupReorderBehavior() {
|
|
4328
|
-
this.cleanupListeners.forEach((dispose) => dispose());
|
|
4329
|
-
this.cleanupListeners = [];
|
|
4330
|
-
if (this.observer) {
|
|
4331
|
-
this.observer.disconnect();
|
|
4332
|
-
this.observer = undefined;
|
|
4333
|
-
}
|
|
4334
|
-
const tbody = this.getTbody();
|
|
4335
|
-
if (tbody) {
|
|
4336
|
-
this.setRowsDraggable(tbody, false);
|
|
4337
|
-
}
|
|
4338
|
-
this.draggedRow = null;
|
|
4339
|
-
}
|
|
4340
|
-
get isReorderEnabled() {
|
|
4341
|
-
return this.reorderRows;
|
|
4342
|
-
}
|
|
4343
|
-
getTbody() {
|
|
4344
|
-
var _a, _b;
|
|
4345
|
-
return (_b = (_a = this.tableElement) === null || _a === void 0 ? void 0 : _a.nativeElement.tBodies.item(0)) !== null && _b !== void 0 ? _b : null;
|
|
4346
|
-
}
|
|
4347
|
-
setRowsDraggable(tbody, enabled) {
|
|
4348
|
-
const rows = Array.from(tbody.rows);
|
|
4349
|
-
rows.forEach((row) => {
|
|
4350
|
-
this.syncAutoDragHandle(row, enabled);
|
|
4351
|
-
row.draggable = false;
|
|
4352
|
-
if (!enabled) {
|
|
4353
|
-
delete row.dataset['dragging'];
|
|
4354
|
-
delete row.dataset['dragArmed'];
|
|
4355
|
-
}
|
|
4356
|
-
});
|
|
4357
|
-
}
|
|
4358
|
-
syncAutoDragHandle(row, enabled) {
|
|
4359
|
-
const firstCell = row.cells.item(0);
|
|
4360
|
-
if (!firstCell) {
|
|
4361
|
-
return;
|
|
4362
|
-
}
|
|
4363
|
-
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
4364
|
-
if (!enabled) {
|
|
4365
|
-
existingAutoHandle === null || existingAutoHandle === void 0 ? void 0 : existingAutoHandle.remove();
|
|
4366
|
-
return;
|
|
4367
|
-
}
|
|
4368
|
-
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
4369
|
-
if (hasCustomHandle || existingAutoHandle) {
|
|
4370
|
-
return;
|
|
4371
|
-
}
|
|
4372
|
-
const button = this.renderer.createElement('button');
|
|
4373
|
-
this.renderer.setAttribute(button, 'type', 'button');
|
|
4374
|
-
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
4375
|
-
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
4376
|
-
this.renderer.addClass(button, 'inline-flex');
|
|
4377
|
-
this.renderer.addClass(button, 'h-7');
|
|
4378
|
-
this.renderer.addClass(button, 'w-7');
|
|
4379
|
-
this.renderer.addClass(button, 'items-center');
|
|
4380
|
-
this.renderer.addClass(button, 'justify-center');
|
|
4381
|
-
this.renderer.addClass(button, 'cursor-grab');
|
|
4382
|
-
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
4383
|
-
this.renderer.addClass(button, 'text-muted-foreground');
|
|
4384
|
-
const dots = this.renderer.createElement('span');
|
|
4385
|
-
this.renderer.addClass(dots, 'text-sm');
|
|
4386
|
-
this.renderer.addClass(dots, 'leading-none');
|
|
4387
|
-
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
4388
|
-
this.renderer.appendChild(button, dots);
|
|
4389
|
-
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
4390
|
-
}
|
|
4391
|
-
onDragStart(event) {
|
|
4392
|
-
const target = event.target;
|
|
4393
|
-
const row = target === null || target === void 0 ? void 0 : target.closest('tr');
|
|
4394
|
-
if (!row) {
|
|
4395
|
-
return;
|
|
4396
|
-
}
|
|
4397
|
-
const handle = target === null || target === void 0 ? void 0 : target.closest(this.dragHandleSelector);
|
|
4398
|
-
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
4399
|
-
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
4400
|
-
event.preventDefault();
|
|
4401
|
-
return;
|
|
4402
|
-
}
|
|
4403
|
-
this.draggedRow = row;
|
|
4404
|
-
this.draggedRow.dataset['dragging'] = 'true';
|
|
4405
|
-
if (event.dataTransfer) {
|
|
4406
|
-
event.dataTransfer.effectAllowed = 'move';
|
|
4407
|
-
event.dataTransfer.setData('text/plain', '');
|
|
4408
|
-
}
|
|
4409
|
-
}
|
|
4410
|
-
onDragOver(event, tbody) {
|
|
4411
|
-
if (!this.draggedRow) {
|
|
4412
|
-
return;
|
|
4413
|
-
}
|
|
4414
|
-
event.preventDefault();
|
|
4415
|
-
const target = event.target;
|
|
4416
|
-
const targetRow = target === null || target === void 0 ? void 0 : target.closest('tr');
|
|
4417
|
-
if (!targetRow || targetRow === this.draggedRow) {
|
|
4418
|
-
return;
|
|
4419
|
-
}
|
|
4420
|
-
const rect = targetRow.getBoundingClientRect();
|
|
4421
|
-
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
4422
|
-
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
4423
|
-
}
|
|
4424
|
-
onDrop(event) {
|
|
4425
|
-
event.preventDefault();
|
|
4426
|
-
}
|
|
4427
|
-
onDragEnd() {
|
|
4428
|
-
const tbody = this.getTbody();
|
|
4429
|
-
if (tbody) {
|
|
4430
|
-
Array.from(tbody.rows).forEach((row) => {
|
|
4431
|
-
row.draggable = false;
|
|
4432
|
-
delete row.dataset['dragArmed'];
|
|
4433
|
-
});
|
|
4434
|
-
}
|
|
4435
|
-
if (this.draggedRow) {
|
|
4436
|
-
delete this.draggedRow.dataset['dragging'];
|
|
4437
|
-
this.draggedRow = null;
|
|
4438
|
-
}
|
|
4439
|
-
if (!tbody) {
|
|
4440
|
-
return;
|
|
4441
|
-
}
|
|
4442
|
-
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
4443
|
-
this.rowOrderChange.emit(order);
|
|
4444
|
-
}
|
|
4445
|
-
armDragFromHandle(event) {
|
|
4446
|
-
const target = event.target;
|
|
4447
|
-
const handle = target === null || target === void 0 ? void 0 : target.closest(this.dragHandleSelector);
|
|
4448
|
-
if (!handle) {
|
|
4449
|
-
return;
|
|
4450
|
-
}
|
|
4451
|
-
const row = handle.closest('tr');
|
|
4452
|
-
if (!row) {
|
|
4453
|
-
return;
|
|
4454
|
-
}
|
|
4455
|
-
row.draggable = true;
|
|
4456
|
-
row.dataset['dragArmed'] = 'true';
|
|
4457
|
-
}
|
|
4458
|
-
}
|
|
4459
|
-
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
4460
|
-
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 });
|
|
4461
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
4462
|
-
type: Component,
|
|
4463
|
-
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" }]
|
|
4464
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
4465
|
-
type: Input
|
|
4466
|
-
}], reorderRows: [{
|
|
4467
|
-
type: Input
|
|
4468
|
-
}], dragHandleSelector: [{
|
|
4469
|
-
type: Input
|
|
4470
|
-
}], className: [{
|
|
4471
|
-
type: Input
|
|
4472
|
-
}], rowOrderChange: [{
|
|
4473
|
-
type: Output
|
|
4474
|
-
}], tableElement: [{
|
|
4475
|
-
type: ViewChild,
|
|
4476
|
-
args: ['tableElement']
|
|
4477
|
-
}] } });
|
|
4478
|
-
|
|
4479
5535
|
class PdmTabsComponent {
|
|
4480
5536
|
constructor(cdr) {
|
|
4481
5537
|
this.cdr = cdr;
|
|
@@ -4493,10 +5549,10 @@ class PdmTabsComponent {
|
|
|
4493
5549
|
}
|
|
4494
5550
|
}
|
|
4495
5551
|
PdmTabsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4496
|
-
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
|
|
5552
|
+
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 });
|
|
4497
5553
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, decorators: [{
|
|
4498
5554
|
type: Component,
|
|
4499
|
-
args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div
|
|
5555
|
+
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" }]
|
|
4500
5556
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
|
|
4501
5557
|
type: Input
|
|
4502
5558
|
}], value: [{
|
|
@@ -4647,10 +5703,10 @@ class PdmTooltipComponent {
|
|
|
4647
5703
|
}
|
|
4648
5704
|
}
|
|
4649
5705
|
PdmTooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4650
|
-
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-
|
|
5706
|
+
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 });
|
|
4651
5707
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, decorators: [{
|
|
4652
5708
|
type: Component,
|
|
4653
|
-
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-
|
|
5709
|
+
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" }]
|
|
4654
5710
|
}], propDecorators: { text: [{
|
|
4655
5711
|
type: Input
|
|
4656
5712
|
}], side: [{
|
|
@@ -4681,6 +5737,7 @@ const COMPONENTS = [
|
|
|
4681
5737
|
PdmDataTableComponent,
|
|
4682
5738
|
PdmDatePickerComponent,
|
|
4683
5739
|
PdmDialogComponent,
|
|
5740
|
+
PdmDraggableTableComponent,
|
|
4684
5741
|
PdmDropdownMenuComponent,
|
|
4685
5742
|
PdmDrawerComponent,
|
|
4686
5743
|
PdmEmptyComponent,
|
|
@@ -4744,6 +5801,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4744
5801
|
PdmDataTableComponent,
|
|
4745
5802
|
PdmDatePickerComponent,
|
|
4746
5803
|
PdmDialogComponent,
|
|
5804
|
+
PdmDraggableTableComponent,
|
|
4747
5805
|
PdmDropdownMenuComponent,
|
|
4748
5806
|
PdmDrawerComponent,
|
|
4749
5807
|
PdmEmptyComponent,
|
|
@@ -4802,6 +5860,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4802
5860
|
PdmDataTableComponent,
|
|
4803
5861
|
PdmDatePickerComponent,
|
|
4804
5862
|
PdmDialogComponent,
|
|
5863
|
+
PdmDraggableTableComponent,
|
|
4805
5864
|
PdmDropdownMenuComponent,
|
|
4806
5865
|
PdmDrawerComponent,
|
|
4807
5866
|
PdmEmptyComponent,
|
|
@@ -4854,5 +5913,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4854
5913
|
* Generated bundle index. Do not edit.
|
|
4855
5914
|
*/
|
|
4856
5915
|
|
|
4857
|
-
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 };
|
|
5916
|
+
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 };
|
|
4858
5917
|
//# sourceMappingURL=pdm-ui-kit.mjs.map
|