pdm-ui-kit 0.1.49 → 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 +25 -7
- 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 +16 -8
- 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 +138 -10
- package/esm2020/lib/components/dropdown-menu/dropdown-menu.component.mjs +6 -3
- package/esm2020/lib/components/hover-card/hover-card.component.mjs +3 -3
- package/esm2020/lib/components/menubar/menubar.component.mjs +38 -7
- 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 +19 -11
- package/esm2020/lib/components/select/select.component.mjs +8 -4
- package/esm2020/lib/components/sheet/sheet.component.mjs +88 -11
- 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/overlay/pdm-outside-click.directive.mjs +86 -0
- package/esm2020/lib/pdm-ui-kit.module.mjs +9 -1
- package/esm2020/lib/utils/responsive.mjs +143 -0
- package/esm2020/lib/utils/z-index.mjs +93 -0
- package/esm2020/public-api.mjs +5 -1
- package/fesm2015/pdm-ui-kit.mjs +1625 -370
- package/fesm2015/pdm-ui-kit.mjs.map +1 -1
- package/fesm2020/pdm-ui-kit.mjs +1620 -367
- package/fesm2020/pdm-ui-kit.mjs.map +1 -1
- package/lib/components/alert-dialog/alert-dialog.component.d.ts +9 -1
- package/lib/components/breadcrumb/breadcrumb.component.d.ts +23 -1
- package/lib/components/card/card.component.d.ts +32 -19
- package/lib/components/context-menu/context-menu.component.d.ts +6 -3
- 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 +67 -3
- package/lib/components/menubar/menubar.component.d.ts +10 -2
- package/lib/components/navigation-menu/navigation-menu.component.d.ts +22 -1
- package/lib/components/popover/popover.component.d.ts +6 -3
- package/lib/components/sheet/sheet.component.d.ts +34 -1
- package/lib/components/sidebar/sidebar.component.d.ts +39 -1
- package/lib/components/table/table.component.d.ts +46 -25
- package/lib/overlay/pdm-outside-click.directive.d.ts +40 -0
- package/lib/pdm-ui-kit.module.d.ts +42 -40
- 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 +4 -0
package/fesm2020/pdm-ui-kit.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as i1 from '@angular/common';
|
|
2
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
+
import { isPlatformBrowser, DOCUMENT, CommonModule } from '@angular/common';
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
|
-
import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChild, ViewChildren, Directive, ContentChildren, NgModule } from '@angular/core';
|
|
4
|
+
import { EventEmitter, Component, ChangeDetectionStrategy, Input, Output, HostListener, ViewChild, ViewChildren, ElementRef, PLATFORM_ID, Directive, Inject, ContentChildren, NgModule } from '@angular/core';
|
|
5
5
|
import * as i1$2 from '@angular/cdk/overlay';
|
|
6
6
|
import { OverlayModule } from '@angular/cdk/overlay';
|
|
7
7
|
import { icons } from 'lucide';
|
|
@@ -90,35 +90,51 @@ class PdmAlertDialogComponent {
|
|
|
90
90
|
this.confirmText = 'Continue';
|
|
91
91
|
this.cancelText = 'Cancel';
|
|
92
92
|
this.className = '';
|
|
93
|
+
/** Close when the ESC key is pressed. Default: `true`. */
|
|
94
|
+
this.closeOnEsc = true;
|
|
93
95
|
this.openChange = new EventEmitter();
|
|
94
96
|
this.confirm = new EventEmitter();
|
|
95
97
|
this.cancel = new EventEmitter();
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Returns `true` when at least one consumer listens to `openChange`.
|
|
101
|
+
* - **Controlled** (has observers): parent manages `open` via two-way binding → only emit.
|
|
102
|
+
* - **Uncontrolled** (no observers): we own the `open` state → mutate it locally.
|
|
103
|
+
*/
|
|
104
|
+
get isControlled() {
|
|
105
|
+
return this.openChange.observed;
|
|
106
|
+
}
|
|
97
107
|
onTriggerClick() {
|
|
98
|
-
this.
|
|
108
|
+
if (!this.isControlled) {
|
|
109
|
+
this.open = true;
|
|
110
|
+
}
|
|
99
111
|
this.openChange.emit(true);
|
|
100
112
|
}
|
|
101
113
|
onCancel() {
|
|
102
114
|
this.cancel.emit();
|
|
103
|
-
this.
|
|
115
|
+
if (!this.isControlled) {
|
|
116
|
+
this.open = false;
|
|
117
|
+
}
|
|
104
118
|
this.openChange.emit(false);
|
|
105
119
|
}
|
|
106
120
|
onConfirm() {
|
|
107
121
|
this.confirm.emit();
|
|
108
|
-
this.
|
|
122
|
+
if (!this.isControlled) {
|
|
123
|
+
this.open = false;
|
|
124
|
+
}
|
|
109
125
|
this.openChange.emit(false);
|
|
110
126
|
}
|
|
111
127
|
onEsc() {
|
|
112
|
-
if (this.open) {
|
|
128
|
+
if (this.open && this.closeOnEsc) {
|
|
113
129
|
this.onCancel();
|
|
114
130
|
}
|
|
115
131
|
}
|
|
116
132
|
}
|
|
117
133
|
PdmAlertDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
118
|
-
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" }, outputs: { openChange: "openChange", confirm: "confirm", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-
|
|
134
|
+
PdmAlertDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmAlertDialogComponent, selector: "pdm-alert-dialog", inputs: { open: "open", showTrigger: "showTrigger", triggerText: "triggerText", title: "title", description: "description", confirmText: "confirmText", cancelText: "cancelText", className: "className", closeOnEsc: "closeOnEsc" }, outputs: { openChange: "openChange", confirm: "confirm", cancel: "cancel" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-[60] w-full max-w-lg rounded-lg border border-border bg-background p-6 text-foreground shadow-lg',\n className\n ]\"\n >\n <div class=\"flex flex-col gap-2\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <div class=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onCancel()\"\n >\n {{ cancelText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm\"\n (click)=\"onConfirm()\"\n >\n {{ confirmText }}\n </button>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
119
135
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, decorators: [{
|
|
120
136
|
type: Component,
|
|
121
|
-
args: [{ selector: 'pdm-alert-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-
|
|
137
|
+
args: [{ selector: 'pdm-alert-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<button\n *ngIf=\"showTrigger && !open\"\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onTriggerClick()\"\n>\n {{ triggerText }}\n</button>\n\n<div *ngIf=\"open\" class=\"fixed inset-0 z-50 flex items-center justify-center p-5\">\n <div class=\"absolute inset-0 bg-foreground/30\" (click)=\"onCancel()\"></div>\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n [ngClass]=\"[\n 'relative z-[60] w-full max-w-lg rounded-lg border border-border bg-background p-6 text-foreground shadow-lg',\n className\n ]\"\n >\n <div class=\"flex flex-col gap-2\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <div class=\"mt-4 flex items-center justify-end gap-2\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm\"\n (click)=\"onCancel()\"\n >\n {{ cancelText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm\"\n (click)=\"onConfirm()\"\n >\n {{ confirmText }}\n </button>\n </div>\n </section>\n</div>\n" }]
|
|
122
138
|
}], propDecorators: { open: [{
|
|
123
139
|
type: Input
|
|
124
140
|
}], showTrigger: [{
|
|
@@ -135,6 +151,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
135
151
|
type: Input
|
|
136
152
|
}], className: [{
|
|
137
153
|
type: Input
|
|
154
|
+
}], closeOnEsc: [{
|
|
155
|
+
type: Input
|
|
138
156
|
}], openChange: [{
|
|
139
157
|
type: Output
|
|
140
158
|
}], confirm: [{
|
|
@@ -237,30 +255,63 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
237
255
|
type: Input
|
|
238
256
|
}] } });
|
|
239
257
|
|
|
258
|
+
/**
|
|
259
|
+
* Breadcrumb component con soporte responsive
|
|
260
|
+
*
|
|
261
|
+
* MEJORADO en v0.2.0:
|
|
262
|
+
* - Modo responsive real con overflow-x-auto
|
|
263
|
+
* - Collapse inteligente en mobile
|
|
264
|
+
*
|
|
265
|
+
* @example
|
|
266
|
+
* <pdm-breadcrumb
|
|
267
|
+
* mode="responsive"
|
|
268
|
+
* [items]="['Home', 'Products', 'Electronics', 'Laptops']">
|
|
269
|
+
* </pdm-breadcrumb>
|
|
270
|
+
*/
|
|
240
271
|
class PdmBreadcrumbComponent {
|
|
241
272
|
constructor() {
|
|
242
273
|
this.mode = 'link-component';
|
|
243
274
|
this.items = ['Home', 'Components', 'Breadcrumb'];
|
|
244
275
|
this.className = '';
|
|
276
|
+
/**
|
|
277
|
+
* Cantidad mínima de items para mostrar en mobile cuando mode="responsive"
|
|
278
|
+
* Default: 2 (primer y último item)
|
|
279
|
+
*/
|
|
280
|
+
this.minItemsMobile = 2;
|
|
245
281
|
}
|
|
246
282
|
get renderedItems() {
|
|
247
|
-
if (
|
|
283
|
+
if (this.mode === 'collapsed' && this.items.length > 3) {
|
|
248
284
|
return [this.items[0], '...', this.items[this.items.length - 2], this.items[this.items.length - 1]];
|
|
249
285
|
}
|
|
286
|
+
// Responsive mode: no collapse en el TS, se maneja en el template con CSS
|
|
250
287
|
return this.items;
|
|
251
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Determina si un item debe estar visible en mobile (modo responsive)
|
|
291
|
+
*/
|
|
292
|
+
shouldShowInMobile(index) {
|
|
293
|
+
if (this.mode !== 'responsive')
|
|
294
|
+
return true;
|
|
295
|
+
const totalItems = this.items.length;
|
|
296
|
+
if (totalItems <= this.minItemsMobile)
|
|
297
|
+
return true;
|
|
298
|
+
// Siempre mostrar primero y último
|
|
299
|
+
return index === 0 || index === totalItems - 1;
|
|
300
|
+
}
|
|
252
301
|
}
|
|
253
302
|
PdmBreadcrumbComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
254
|
-
PdmBreadcrumbComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmBreadcrumbComponent, selector: "pdm-breadcrumb", inputs: { mode: "mode", items: "items", className: "className" }, ngImport: i0, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
303
|
+
PdmBreadcrumbComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmBreadcrumbComponent, selector: "pdm-breadcrumb", inputs: { mode: "mode", items: "items", className: "className", minItemsMobile: "minItemsMobile" }, ngImport: i0, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"[\n 'inline-flex items-center gap-1.5 text-sm',\n mode === 'responsive' ? 'overflow-x-auto max-w-full pb-1 scrollbar-thin' : '',\n className\n ]\"\n>\n <ng-container *ngFor=\"let item of renderedItems; let i = index; let last = last\">\n <!-- Item text -->\n <span \n [ngClass]=\"[\n last ? 'text-foreground font-medium' : 'text-muted-foreground hover:text-foreground transition-colors cursor-pointer',\n mode === 'responsive' && !shouldShowInMobile(i) ? 'hidden sm:inline' : '',\n 'whitespace-nowrap'\n ]\">\n {{ item }}\n </span>\n\n <!-- Separator -->\n <ng-container *ngIf=\"!last\">\n <span \n [ngClass]=\"[\n 'inline-flex h-6 w-6 flex-shrink-0 items-center justify-center text-muted-foreground',\n mode === 'responsive' && !shouldShowInMobile(i) && !shouldShowInMobile(i + 1) ? 'hidden sm:inline-flex' : ''\n ]\" \n aria-hidden=\"true\">\n <!-- Custom separator (slash) -->\n <svg\n *ngIf=\"mode === 'custom-separator' && item !== '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M8 20L16 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n \n <!-- Default separator (chevron) -->\n <svg\n *ngIf=\"(mode !== 'custom-separator' && item !== '...') || item === '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n \n <!-- Ellipsis indicator for responsive mode (only shown when items are hidden) -->\n <span \n *ngIf=\"mode === 'responsive' && !shouldShowInMobile(i) && i === 0\"\n class=\"inline-flex sm:hidden text-muted-foreground\">\n ...\n </span>\n </ng-container>\n\n <!-- Dropdown indicator -->\n <ng-container *ngIf=\"mode === 'dropdown' && i === 1 && item !== '...' && !last\">\n <span class=\"-ml-2 inline-flex h-6 w-6 items-center justify-center text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </ng-container>\n </ng-container>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
255
304
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, decorators: [{
|
|
256
305
|
type: Component,
|
|
257
|
-
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
306
|
+
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"[\n 'inline-flex items-center gap-1.5 text-sm',\n mode === 'responsive' ? 'overflow-x-auto max-w-full pb-1 scrollbar-thin' : '',\n className\n ]\"\n>\n <ng-container *ngFor=\"let item of renderedItems; let i = index; let last = last\">\n <!-- Item text -->\n <span \n [ngClass]=\"[\n last ? 'text-foreground font-medium' : 'text-muted-foreground hover:text-foreground transition-colors cursor-pointer',\n mode === 'responsive' && !shouldShowInMobile(i) ? 'hidden sm:inline' : '',\n 'whitespace-nowrap'\n ]\">\n {{ item }}\n </span>\n\n <!-- Separator -->\n <ng-container *ngIf=\"!last\">\n <span \n [ngClass]=\"[\n 'inline-flex h-6 w-6 flex-shrink-0 items-center justify-center text-muted-foreground',\n mode === 'responsive' && !shouldShowInMobile(i) && !shouldShowInMobile(i + 1) ? 'hidden sm:inline-flex' : ''\n ]\" \n aria-hidden=\"true\">\n <!-- Custom separator (slash) -->\n <svg\n *ngIf=\"mode === 'custom-separator' && item !== '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M8 20L16 4\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" />\n </svg>\n \n <!-- Default separator (chevron) -->\n <svg\n *ngIf=\"(mode !== 'custom-separator' && item !== '...') || item === '...'\"\n viewBox=\"0 0 24 24\"\n class=\"h-4 w-4\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n \n <!-- Ellipsis indicator for responsive mode (only shown when items are hidden) -->\n <span \n *ngIf=\"mode === 'responsive' && !shouldShowInMobile(i) && i === 0\"\n class=\"inline-flex sm:hidden text-muted-foreground\">\n ...\n </span>\n </ng-container>\n\n <!-- Dropdown indicator -->\n <ng-container *ngIf=\"mode === 'dropdown' && i === 1 && item !== '...' && !last\">\n <span class=\"-ml-2 inline-flex h-6 w-6 items-center justify-center text-muted-foreground\" aria-hidden=\"true\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n </ng-container>\n </ng-container>\n</nav>\n" }]
|
|
258
307
|
}], propDecorators: { mode: [{
|
|
259
308
|
type: Input
|
|
260
309
|
}], items: [{
|
|
261
310
|
type: Input
|
|
262
311
|
}], className: [{
|
|
263
312
|
type: Input
|
|
313
|
+
}], minItemsMobile: [{
|
|
314
|
+
type: Input
|
|
264
315
|
}] } });
|
|
265
316
|
|
|
266
317
|
class PdmButtonGroupComponent {
|
|
@@ -1040,10 +1091,10 @@ class PdmCalendarComponent {
|
|
|
1040
1091
|
}
|
|
1041
1092
|
}
|
|
1042
1093
|
PdmCalendarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1043
|
-
PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { variant: "variant", className: "className", disabledDates: "disabledDates", minDate: "minDate", maxDate: "maxDate", minYear: "minYear", maxYear: "maxYear", isDateDisabled: "isDateDisabled", allowSameDayRange: "allowSameDayRange", readonly: "readonly", value: "value", rangeValue: "rangeValue", month: "month" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", monthChange: "monthChange", dateClick: "dateClick", disabledDateClick: "disabledDateClick" }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1094
|
+
PdmCalendarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCalendarComponent, selector: "pdm-calendar", inputs: { variant: "variant", className: "className", disabledDates: "disabledDates", minDate: "minDate", maxDate: "maxDate", minYear: "minYear", maxYear: "maxYear", isDateDisabled: "isDateDisabled", allowSameDayRange: "allowSameDayRange", readonly: "readonly", value: "value", rangeValue: "rangeValue", month: "month" }, outputs: { valueChange: "valueChange", rangeValueChange: "rangeValueChange", monthChange: "monthChange", dateClick: "dateClick", disabledDateClick: "disabledDateClick" }, ngImport: i0, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1044
1095
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCalendarComponent, decorators: [{
|
|
1045
1096
|
type: Component,
|
|
1046
|
-
args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
1097
|
+
args: [{ selector: 'pdm-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"rootClasses\" [ngStyle]=\"rootStyle\">\n <div *ngFor=\"let month of visibleMonths; let monthIndex = index; trackBy: trackByIndex\" [ngClass]=\"monthPanelClasses(monthIndex)\">\n <div [ngClass]=\"headerClasses(month)\">\n <button\n *ngIf=\"month.showPrevButton; else prevPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Previous month\"\n (click)=\"goToPreviousMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m15 18-6-6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #prevPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n\n <ng-container *ngIf=\"month.titleStyle === 'dropdowns'; else plainTitle\">\n <div [ngClass]=\"dropdownWrapClasses()\">\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[72px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderMonth\"\n aria-label=\"Month\"\n (change)=\"onSingleMonthChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let monthOption of monthOptions\"\n [value]=\"monthOption.value\"\n [selected]=\"monthOption.value === singleHeaderMonth\"\n >\n {{ monthOption.label }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n <div [ngClass]=\"dropdownClasses('w-16 sm:w-[82px]')\">\n <select\n [ngClass]=\"dropdownSelectClasses()\"\n [ngStyle]=\"dropdownSelectStyle\"\n [value]=\"singleHeaderYear\"\n aria-label=\"Year\"\n (change)=\"onSingleYearChange($any($event.target).value)\"\n >\n <option\n *ngFor=\"let year of yearOptions\"\n [value]=\"year\"\n [selected]=\"year === singleHeaderYear\"\n >\n {{ year }}\n </option>\n </select>\n <svg viewBox=\"0 0 24 24\" class=\"h-3 w-3 text-foreground\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m6 9 6 6 6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </div>\n </div>\n </ng-container>\n\n <ng-template #plainTitle>\n <div class=\"flex min-w-0 flex-1 items-center justify-center\">\n <p class=\"m-0 text-foreground text-center text-sm font-medium leading-5\">\n {{ month.title }}\n </p>\n </div>\n </ng-template>\n\n <button\n *ngIf=\"month.showNextButton; else nextPlaceholder\"\n type=\"button\"\n [ngClass]=\"navButtonClasses()\"\n aria-label=\"Next month\"\n (click)=\"goToNextMonth()\"\n [disabled]=\"readonly\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" aria-hidden=\"true\">\n <path d=\"m9 18 6-6-6-6\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n <ng-template #nextPlaceholder>\n <div [ngClass]=\"navPlaceholderClasses()\" aria-hidden=\"true\"></div>\n </ng-template>\n </div>\n\n <div [ngClass]=\"calendarGridWrapClasses()\">\n <div [ngClass]=\"weekdayRowClasses()\">\n <div *ngFor=\"let day of weekdays; trackBy: trackByIndex\" [ngClass]=\"weekdayCellClasses()\">\n <span>{{ day }}</span>\n </div>\n </div>\n\n <div *ngFor=\"let week of month.weeks; trackBy: trackByIndex\" [ngClass]=\"weekRowClasses()\">\n <div *ngFor=\"let cell of week; trackBy: trackByDate\" [ngClass]=\"dayCellClasses(cell)\">\n <button\n type=\"button\"\n [ngClass]=\"dayButtonClasses(cell)\"\n [disabled]=\"readonly\"\n [attr.aria-selected]=\"cell.selected\"\n [attr.aria-disabled]=\"cell.disabled || readonly\"\n [attr.title]=\"cell.date | date : 'yyyy-MM-dd'\"\n (click)=\"onDatePressed(cell)\"\n >\n <span [ngClass]=\"dayLabelClasses(cell)\">{{ cell.label }}</span>\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n" }]
|
|
1047
1098
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { variant: [{
|
|
1048
1099
|
type: Input
|
|
1049
1100
|
}], className: [{
|
|
@@ -1181,66 +1232,49 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1181
1232
|
type: Output
|
|
1182
1233
|
}] } });
|
|
1183
1234
|
|
|
1235
|
+
/**
|
|
1236
|
+
* Card component - Visual container primitivo
|
|
1237
|
+
*
|
|
1238
|
+
* BREAKING CHANGE en v0.2.0: variant="login" eliminado.
|
|
1239
|
+
* Card es ahora un componente UI puro sin lógica de negocio.
|
|
1240
|
+
*
|
|
1241
|
+
* Para crear un login form, componer con primitivos:
|
|
1242
|
+
*
|
|
1243
|
+
* @example
|
|
1244
|
+
* <pdm-card>
|
|
1245
|
+
* <div pdmCardHeader>
|
|
1246
|
+
* <h3 class="text-lg font-semibold">Login</h3>
|
|
1247
|
+
* <p class="text-sm text-muted-foreground">Enter your credentials</p>
|
|
1248
|
+
* </div>
|
|
1249
|
+
* <div pdmCardContent>
|
|
1250
|
+
* <form [formGroup]="form">
|
|
1251
|
+
* <pdm-field>
|
|
1252
|
+
* <pdm-label>Email</pdm-label>
|
|
1253
|
+
* <pdm-input type="email" formControlName="email" />
|
|
1254
|
+
* </pdm-field>
|
|
1255
|
+
* <pdm-field>
|
|
1256
|
+
* <pdm-label>Password</pdm-label>
|
|
1257
|
+
* <pdm-input-password formControlName="password" />
|
|
1258
|
+
* </pdm-field>
|
|
1259
|
+
* </form>
|
|
1260
|
+
* </div>
|
|
1261
|
+
* <div pdmCardFooter>
|
|
1262
|
+
* <pdm-button (click)="onLogin()">Login</pdm-button>
|
|
1263
|
+
* </div>
|
|
1264
|
+
* </pdm-card>
|
|
1265
|
+
*/
|
|
1184
1266
|
class PdmCardComponent {
|
|
1185
1267
|
constructor() {
|
|
1186
|
-
this.variant = 'default';
|
|
1187
1268
|
this.className = '';
|
|
1188
|
-
this.title = 'Login to your account';
|
|
1189
|
-
this.description = 'Enter your email below to login to your account';
|
|
1190
|
-
this.actionText = 'Sign up';
|
|
1191
|
-
this.emailLabel = 'Email';
|
|
1192
|
-
this.emailPlaceholder = 'm@example.com';
|
|
1193
|
-
this.passwordLabel = 'Password';
|
|
1194
|
-
this.passwordHint = 'Forgot password?';
|
|
1195
|
-
this.primaryActionText = 'Login';
|
|
1196
|
-
this.secondaryActionText = 'Login with Google';
|
|
1197
|
-
this.primaryAction = new EventEmitter();
|
|
1198
|
-
this.secondaryAction = new EventEmitter();
|
|
1199
|
-
this.actionPressed = new EventEmitter();
|
|
1200
|
-
}
|
|
1201
|
-
onPrimaryAction() {
|
|
1202
|
-
this.primaryAction.emit();
|
|
1203
|
-
}
|
|
1204
|
-
onSecondaryAction() {
|
|
1205
|
-
this.secondaryAction.emit();
|
|
1206
|
-
}
|
|
1207
|
-
onActionPressed() {
|
|
1208
|
-
this.actionPressed.emit();
|
|
1209
1269
|
}
|
|
1210
1270
|
}
|
|
1211
1271
|
PdmCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1212
|
-
PdmCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCardComponent, selector: "pdm-card", inputs: {
|
|
1272
|
+
PdmCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCardComponent, selector: "pdm-card", inputs: { className: "className" }, ngImport: i0, template: "<section\n [ngClass]=\"[\n 'w-full rounded-lg border border-border bg-background py-6 shadow-sm',\n className\n ]\"\n>\n <div class=\"flex w-full flex-col gap-6\">\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardHeader]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardContent]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardFooter]\"></ng-content>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1213
1273
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCardComponent, decorators: [{
|
|
1214
1274
|
type: Component,
|
|
1215
|
-
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 <
|
|
1216
|
-
}], propDecorators: {
|
|
1217
|
-
type: Input
|
|
1218
|
-
}], className: [{
|
|
1219
|
-
type: Input
|
|
1220
|
-
}], title: [{
|
|
1221
|
-
type: Input
|
|
1222
|
-
}], description: [{
|
|
1223
|
-
type: Input
|
|
1224
|
-
}], actionText: [{
|
|
1225
|
-
type: Input
|
|
1226
|
-
}], emailLabel: [{
|
|
1227
|
-
type: Input
|
|
1228
|
-
}], emailPlaceholder: [{
|
|
1229
|
-
type: Input
|
|
1230
|
-
}], passwordLabel: [{
|
|
1231
|
-
type: Input
|
|
1232
|
-
}], passwordHint: [{
|
|
1233
|
-
type: Input
|
|
1234
|
-
}], primaryActionText: [{
|
|
1235
|
-
type: Input
|
|
1236
|
-
}], secondaryActionText: [{
|
|
1275
|
+
args: [{ selector: 'pdm-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section\n [ngClass]=\"[\n 'w-full rounded-lg border border-border bg-background py-6 shadow-sm',\n className\n ]\"\n>\n <div class=\"flex w-full flex-col gap-6\">\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardHeader]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardContent]\"></ng-content>\n </div>\n <div class=\"px-6\">\n <ng-content select=\"[pdmCardFooter]\"></ng-content>\n </div>\n </div>\n</section>\n" }]
|
|
1276
|
+
}], propDecorators: { className: [{
|
|
1237
1277
|
type: Input
|
|
1238
|
-
}], primaryAction: [{
|
|
1239
|
-
type: Output
|
|
1240
|
-
}], secondaryAction: [{
|
|
1241
|
-
type: Output
|
|
1242
|
-
}], actionPressed: [{
|
|
1243
|
-
type: Output
|
|
1244
1278
|
}] } });
|
|
1245
1279
|
|
|
1246
1280
|
class PdmChartComponent {
|
|
@@ -1735,10 +1769,10 @@ class PdmCommandComponent {
|
|
|
1735
1769
|
}
|
|
1736
1770
|
}
|
|
1737
1771
|
PdmCommandComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1738
|
-
PdmCommandComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCommandComponent, selector: "pdm-command", inputs: { open: "open", hintLabel: "hintLabel", hintKey: "hintKey", placeholder: "placeholder", emptyMessage: "emptyMessage", items: "items", className: "className" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-
|
|
1772
|
+
PdmCommandComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmCommandComponent, selector: "pdm-command", inputs: { open: "open", hintLabel: "hintLabel", hintKey: "hintKey", placeholder: "placeholder", emptyMessage: "emptyMessage", items: "items", className: "className" }, outputs: { itemSelect: "itemSelect", openChange: "openChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-[50vh] overflow-y-auto p-1 md:max-h-72\">\n <ng-container *ngFor=\"let group of groupedItems; let groupIndex = index\">\n <div *ngIf=\"group.name\" class=\"px-2 py-1.5 text-xs text-muted-foreground\">{{ group.name }}</div>\n <button\n *ngFor=\"let item of group.items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"[\n item.disabled ? 'opacity-50' : '',\n item.label === 'Calendar' ? 'bg-accent text-accent-foreground' : ''\n ]\"\n (click)=\"select(item.value)\"\n >\n <span class=\"inline-flex h-4 w-4 items-center justify-center text-foreground\">\n <pdm-icon *ngIf=\"item.icon\" [name]=\"item.icon\" [size]=\"16\" [decorative]=\"true\"></pdm-icon>\n </span>\n <span class=\"min-w-0 flex-1 text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n </button>\n <div *ngIf=\"groupIndex === 0 && groupedItems.length > 1\" class=\"my-1 border-t border-border\"></div>\n </ng-container>\n\n <p *ngIf=\"filteredItems.length === 0\" class=\"m-0 py-6 text-center text-sm text-muted-foreground\">{{ emptyMessage }}</p>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1739
1773
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmCommandComponent, decorators: [{
|
|
1740
1774
|
type: Component,
|
|
1741
|
-
args: [{ selector: 'pdm-command', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-
|
|
1775
|
+
args: [{ selector: 'pdm-command', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div *ngIf=\"!open\" class=\"flex items-center gap-1\">\n <span class=\"text-sm font-medium text-muted-foreground\">{{ hintLabel }}</span>\n <button\n type=\"button\"\n class=\"inline-flex h-5 appearance-none items-center gap-0.5 rounded-sm border border-border bg-muted px-1.5\"\n (click)=\"toggleOpen()\"\n >\n <pdm-icon name=\"command\" [size]=\"12\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <span class=\"text-xs text-muted-foreground\">{{ hintKey }}</span>\n </button>\n </div>\n\n <section\n *ngIf=\"open\"\n class=\"flex w-full flex-col overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-md\"\n >\n <div class=\"flex items-center gap-2 border-b border-border px-3\">\n <pdm-icon name=\"search\" [size]=\"16\" className=\"text-muted-foreground\" [decorative]=\"true\"></pdm-icon>\n <input\n type=\"text\"\n [placeholder]=\"placeholder\"\n [value]=\"query\"\n (input)=\"onQueryChange($event)\"\n class=\"h-10 w-full bg-transparent py-3 text-sm text-foreground outline-none placeholder:text-muted-foreground\"\n />\n </div>\n\n <div class=\"max-h-[50vh] overflow-y-auto p-1 md:max-h-72\">\n <ng-container *ngFor=\"let group of groupedItems; let groupIndex = index\">\n <div *ngIf=\"group.name\" class=\"px-2 py-1.5 text-xs text-muted-foreground\">{{ group.name }}</div>\n <button\n *ngFor=\"let item of group.items\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"flex w-full appearance-none items-center gap-2 rounded-sm border-0 bg-transparent px-2 py-1.5 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground\"\n [ngClass]=\"[\n item.disabled ? 'opacity-50' : '',\n item.label === 'Calendar' ? 'bg-accent text-accent-foreground' : ''\n ]\"\n (click)=\"select(item.value)\"\n >\n <span class=\"inline-flex h-4 w-4 items-center justify-center text-foreground\">\n <pdm-icon *ngIf=\"item.icon\" [name]=\"item.icon\" [size]=\"16\" [decorative]=\"true\"></pdm-icon>\n </span>\n <span class=\"min-w-0 flex-1 text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n </button>\n <div *ngIf=\"groupIndex === 0 && groupedItems.length > 1\" class=\"my-1 border-t border-border\"></div>\n </ng-container>\n\n <p *ngIf=\"filteredItems.length === 0\" class=\"m-0 py-6 text-center text-sm text-muted-foreground\">{{ emptyMessage }}</p>\n </div>\n </section>\n</div>\n" }]
|
|
1742
1776
|
}], propDecorators: { open: [{
|
|
1743
1777
|
type: Input
|
|
1744
1778
|
}], hintLabel: [{
|
|
@@ -1785,6 +1819,15 @@ class PdmContextMenuComponent {
|
|
|
1785
1819
|
this.x = 0;
|
|
1786
1820
|
this.y = 0;
|
|
1787
1821
|
}
|
|
1822
|
+
ngOnInit() {
|
|
1823
|
+
this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
|
|
1824
|
+
document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
1825
|
+
}
|
|
1826
|
+
ngOnDestroy() {
|
|
1827
|
+
if (this.boundPointerDown) {
|
|
1828
|
+
document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
1829
|
+
}
|
|
1830
|
+
}
|
|
1788
1831
|
onContextMenu(event) {
|
|
1789
1832
|
event.preventDefault();
|
|
1790
1833
|
this.x = event.clientX;
|
|
@@ -1798,9 +1841,11 @@ class PdmContextMenuComponent {
|
|
|
1798
1841
|
this.open = false;
|
|
1799
1842
|
}
|
|
1800
1843
|
onEsc() {
|
|
1801
|
-
this.open
|
|
1844
|
+
if (this.open) {
|
|
1845
|
+
this.open = false;
|
|
1846
|
+
}
|
|
1802
1847
|
}
|
|
1803
|
-
|
|
1848
|
+
onDocumentPointerDown(event) {
|
|
1804
1849
|
if (!this.open)
|
|
1805
1850
|
return;
|
|
1806
1851
|
const target = event.target;
|
|
@@ -1810,10 +1855,10 @@ class PdmContextMenuComponent {
|
|
|
1810
1855
|
}
|
|
1811
1856
|
}
|
|
1812
1857
|
PdmContextMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
1813
|
-
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()"
|
|
1858
|
+
PdmContextMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmContextMenuComponent, selector: "pdm-context-menu", inputs: { items: "items", className: "className", triggerLabel: "triggerLabel", width: "width", height: "height" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1814
1859
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmContextMenuComponent, decorators: [{
|
|
1815
1860
|
type: Component,
|
|
1816
|
-
args: [{ selector: 'pdm-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-
|
|
1861
|
+
args: [{ selector: 'pdm-context-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative\" [ngClass]=\"className\" (contextmenu)=\"onContextMenu($event)\">\n <div\n class=\"flex items-center justify-center rounded-md border border-dashed border-border\"\n [style.width.px]=\"width\"\n [style.height.px]=\"height\"\n >\n <span class=\"text-sm font-medium text-foreground\">{{ triggerLabel }}</span>\n </div>\n\n <div\n *ngIf=\"open\"\n class=\"fixed z-[70] min-w-48 max-w-xs rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-52\"\n [style.left.px]=\"x + 4\"\n [style.top.px]=\"y + 2\"\n >\n <div>\n <ng-container *ngFor=\"let item of items\">\n <div *ngIf=\"item.type === 'separator'\" class=\"-mx-1 my-1 h-px bg-muted\"></div>\n\n <div *ngIf=\"item.type === 'label'\" class=\"px-2 py-1.5 text-sm font-semibold text-foreground\">\n {{ item.label }}\n </div>\n\n <button\n *ngIf=\"!item.type || item.type === 'item'\"\n type=\"button\"\n [disabled]=\"item.disabled\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent py-1.5 pr-2 text-left text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n [ngClass]=\"item.inset ? 'pl-8' : 'px-2'\"\n (click)=\"select(item)\"\n >\n <span class=\"mr-2 inline-flex w-4 shrink-0 items-center justify-center text-foreground\">\n <svg *ngIf=\"item.checked\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M5 12.5L9.2 16.7L19 7\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n <span *ngIf=\"item.selectedDot\" class=\"h-2 w-2 rounded-full bg-foreground\"></span>\n </span>\n <span class=\"min-w-0 flex-1 truncate text-foreground\">{{ item.label }}</span>\n <span *ngIf=\"item.shortcut\" class=\"text-xs text-muted-foreground\">{{ item.shortcut }}</span>\n <svg *ngIf=\"item.showChevron\" viewBox=\"0 0 24 24\" class=\"h-3.5 w-3.5 text-muted-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 6L15 12L9 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </ng-container>\n </div>\n </div>\n</div>\n" }]
|
|
1817
1862
|
}], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { items: [{
|
|
1818
1863
|
type: Input
|
|
1819
1864
|
}], className: [{
|
|
@@ -1829,36 +1874,461 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1829
1874
|
}], onEsc: [{
|
|
1830
1875
|
type: HostListener,
|
|
1831
1876
|
args: ['document:keydown.escape']
|
|
1832
|
-
}], onDocumentClick: [{
|
|
1833
|
-
type: HostListener,
|
|
1834
|
-
args: ['document:click', ['$event']]
|
|
1835
1877
|
}] } });
|
|
1836
1878
|
|
|
1879
|
+
/**
|
|
1880
|
+
* Sistema de responsive utilities para PDM UI Kit
|
|
1881
|
+
*
|
|
1882
|
+
* Proporciona constantes, tipos y helpers para manejar responsive design
|
|
1883
|
+
* de forma consistente en todos los componentes.
|
|
1884
|
+
*/
|
|
1885
|
+
/**
|
|
1886
|
+
* Breakpoints estándar de Tailwind CSS
|
|
1887
|
+
* Mobile-first approach: los estilos base son para mobile, los breakpoints son MIN-WIDTH
|
|
1888
|
+
*/
|
|
1889
|
+
const BREAKPOINTS = {
|
|
1890
|
+
sm: '640px',
|
|
1891
|
+
md: '768px',
|
|
1892
|
+
lg: '1024px',
|
|
1893
|
+
xl: '1280px',
|
|
1894
|
+
'2xl': '1536px' // extra large desktop
|
|
1895
|
+
};
|
|
1896
|
+
/**
|
|
1897
|
+
* Helper para generar clases responsive de forma programática
|
|
1898
|
+
*
|
|
1899
|
+
* @example
|
|
1900
|
+
* responsive({ default: 'block', sm: 'flex', lg: 'grid' })
|
|
1901
|
+
* // Returns: 'block sm:flex lg:grid'
|
|
1902
|
+
*/
|
|
1903
|
+
function responsive(config) {
|
|
1904
|
+
const classes = [];
|
|
1905
|
+
if (config.default) {
|
|
1906
|
+
classes.push(config.default);
|
|
1907
|
+
}
|
|
1908
|
+
['sm', 'md', 'lg', 'xl', '2xl'].forEach(bp => {
|
|
1909
|
+
if (config[bp]) {
|
|
1910
|
+
classes.push(`${bp}:${config[bp]}`);
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
return classes.join(' ');
|
|
1914
|
+
}
|
|
1915
|
+
/**
|
|
1916
|
+
* Helper para overflow responsive
|
|
1917
|
+
* Maneja el caso común de scroll en mobile, auto en desktop
|
|
1918
|
+
*
|
|
1919
|
+
* @example
|
|
1920
|
+
* overflowResponsive('x', 'scroll', 'auto')
|
|
1921
|
+
* // Returns: 'overflow-x-scroll sm:overflow-x-auto'
|
|
1922
|
+
*/
|
|
1923
|
+
function overflowResponsive(axis, mobile, desktop) {
|
|
1924
|
+
const axisClass = axis === 'both' ? 'overflow' : `overflow-${axis}`;
|
|
1925
|
+
const mobileClass = `${axisClass}-${mobile}`;
|
|
1926
|
+
if (!desktop || desktop === mobile) {
|
|
1927
|
+
return mobileClass;
|
|
1928
|
+
}
|
|
1929
|
+
return `${mobileClass} sm:${axisClass}-${desktop}`;
|
|
1930
|
+
}
|
|
1931
|
+
/**
|
|
1932
|
+
* Helper para spacing responsive
|
|
1933
|
+
* Útil para padding/margin que necesita ajustarse por breakpoint
|
|
1934
|
+
*
|
|
1935
|
+
* @example
|
|
1936
|
+
* spacingResponsive('px', { default: '4', sm: '6', lg: '8' })
|
|
1937
|
+
* // Returns: 'px-4 sm:px-6 lg:px-8'
|
|
1938
|
+
*/
|
|
1939
|
+
function spacingResponsive(property, values) {
|
|
1940
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1941
|
+
acc[key] = `${property}-${value}`;
|
|
1942
|
+
return acc;
|
|
1943
|
+
}, {}));
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Helper para width responsive
|
|
1947
|
+
*
|
|
1948
|
+
* @example
|
|
1949
|
+
* widthResponsive({ default: 'full', sm: 'auto', lg: '1/2' })
|
|
1950
|
+
* // Returns: 'w-full sm:w-auto lg:w-1/2'
|
|
1951
|
+
*/
|
|
1952
|
+
function widthResponsive(values) {
|
|
1953
|
+
return responsive(Object.entries(values).reduce((acc, [key, value]) => {
|
|
1954
|
+
acc[key] = `w-${value}`;
|
|
1955
|
+
return acc;
|
|
1956
|
+
}, {}));
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Clases comunes para containers responsive
|
|
1960
|
+
* Pensadas para wrappers que contienen contenido que puede desbordar
|
|
1961
|
+
*/
|
|
1962
|
+
const RESPONSIVE_CONTAINER = {
|
|
1963
|
+
// Container con scroll horizontal en mobile, contenido visible en desktop
|
|
1964
|
+
tableWrapper: 'relative w-full overflow-x-auto sm:overflow-x-visible',
|
|
1965
|
+
// Container con padding negativo en mobile para scroll edge-to-edge
|
|
1966
|
+
tableWrapperFullBleed: 'relative w-full -mx-4 px-4 overflow-x-auto sm:mx-0 sm:px-0 sm:overflow-x-visible',
|
|
1967
|
+
// Container con max-width responsive
|
|
1968
|
+
contentWrapper: 'w-full mx-auto px-4 sm:px-6 lg:px-8 max-w-screen-2xl',
|
|
1969
|
+
// Container para modals/dialogs
|
|
1970
|
+
modalWrapper: 'w-full max-w-lg mx-auto px-4 sm:px-0',
|
|
1971
|
+
// Container para forms
|
|
1972
|
+
formWrapper: 'w-full max-w-md mx-auto space-y-4'
|
|
1973
|
+
};
|
|
1974
|
+
/**
|
|
1975
|
+
* Clases comunes para display responsive
|
|
1976
|
+
*/
|
|
1977
|
+
const RESPONSIVE_DISPLAY = {
|
|
1978
|
+
// Ocultar en mobile, mostrar en desktop
|
|
1979
|
+
hideOnMobile: 'hidden sm:block',
|
|
1980
|
+
// Mostrar solo en mobile
|
|
1981
|
+
showOnMobile: 'block sm:hidden',
|
|
1982
|
+
// Stack en mobile, flex en desktop
|
|
1983
|
+
stackToFlex: 'flex flex-col sm:flex-row',
|
|
1984
|
+
// Stack en mobile, grid en desktop
|
|
1985
|
+
stackToGrid: 'grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3'
|
|
1986
|
+
};
|
|
1987
|
+
/**
|
|
1988
|
+
* Clases para table responsive strategies
|
|
1989
|
+
*/
|
|
1990
|
+
const TABLE_RESPONSIVE = {
|
|
1991
|
+
// Scroll horizontal (default, más simple)
|
|
1992
|
+
scroll: {
|
|
1993
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
1994
|
+
table: 'w-full min-w-full',
|
|
1995
|
+
cell: 'whitespace-nowrap'
|
|
1996
|
+
},
|
|
1997
|
+
// Permitir wrap del contenido
|
|
1998
|
+
wrap: {
|
|
1999
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2000
|
+
table: 'w-full',
|
|
2001
|
+
cell: 'whitespace-normal break-words'
|
|
2002
|
+
},
|
|
2003
|
+
// Stack en mobile (cada fila se convierte en card)
|
|
2004
|
+
// Requiere lógica adicional en el componente
|
|
2005
|
+
stack: {
|
|
2006
|
+
wrapper: 'relative w-full',
|
|
2007
|
+
table: 'w-full',
|
|
2008
|
+
row: 'block sm:table-row border-b sm:border-b-0',
|
|
2009
|
+
cell: 'block sm:table-cell py-2 sm:py-0 before:content-[attr(data-label)] before:font-medium before:inline-block before:w-32 sm:before:content-none'
|
|
2010
|
+
},
|
|
2011
|
+
// Collapse: ocultar columnas menos importantes en mobile
|
|
2012
|
+
// Se usa con clases de visibility en las columnas específicas
|
|
2013
|
+
collapse: {
|
|
2014
|
+
wrapper: 'relative w-full overflow-x-auto',
|
|
2015
|
+
table: 'w-full',
|
|
2016
|
+
cell: 'whitespace-nowrap',
|
|
2017
|
+
// Estas clases se aplican a columnas opcionales
|
|
2018
|
+
optionalColumn: 'hidden md:table-cell'
|
|
2019
|
+
}
|
|
2020
|
+
};
|
|
2021
|
+
|
|
2022
|
+
/**
|
|
2023
|
+
* Componente base de tabla con soporte responsive
|
|
2024
|
+
*
|
|
2025
|
+
* SIMPLIFICADO: Ya no incluye drag & drop (usar pdm-draggable-table para eso)
|
|
2026
|
+
*
|
|
2027
|
+
* @example
|
|
2028
|
+
* // Tabla simple con scroll horizontal
|
|
2029
|
+
* <pdm-table variant="default">
|
|
2030
|
+
* <thead><tr><th>Name</th><th>Email</th></tr></thead>
|
|
2031
|
+
* <tbody><tr><td>John</td><td>john@example.com</td></tr></tbody>
|
|
2032
|
+
* </pdm-table>
|
|
2033
|
+
*
|
|
2034
|
+
* @example
|
|
2035
|
+
* // Tabla interactiva con wrap en mobile
|
|
2036
|
+
* <pdm-table variant="interactive" responsiveStrategy="wrap">
|
|
2037
|
+
* ...
|
|
2038
|
+
* </pdm-table>
|
|
2039
|
+
*/
|
|
2040
|
+
class PdmTableComponent {
|
|
2041
|
+
constructor() {
|
|
2042
|
+
/**
|
|
2043
|
+
* Variante visual de la tabla
|
|
2044
|
+
* - default: tabla básica sin estilos extra
|
|
2045
|
+
* - data: tabla con bordes y espaciado para data
|
|
2046
|
+
* - interactive: tabla con hover, sticky header y estilos interactivos
|
|
2047
|
+
*/
|
|
2048
|
+
this.variant = 'default';
|
|
2049
|
+
/**
|
|
2050
|
+
* Estrategia responsive para la tabla
|
|
2051
|
+
* - scroll: scroll horizontal en mobile (default, más simple)
|
|
2052
|
+
* - wrap: permite que el contenido haga wrap
|
|
2053
|
+
* - stack: convierte filas en cards en mobile (requiere data-label en celdas)
|
|
2054
|
+
* - collapse: oculta columnas menos importantes en mobile
|
|
2055
|
+
*/
|
|
2056
|
+
this.responsiveStrategy = 'scroll';
|
|
2057
|
+
/**
|
|
2058
|
+
* Clases CSS adicionales para el wrapper
|
|
2059
|
+
*/
|
|
2060
|
+
this.className = '';
|
|
2061
|
+
/**
|
|
2062
|
+
* Si es true, aplica padding negativo en mobile para scroll edge-to-edge
|
|
2063
|
+
* Útil cuando la tabla está dentro de un container con padding
|
|
2064
|
+
*/
|
|
2065
|
+
this.fullBleed = false;
|
|
2066
|
+
}
|
|
2067
|
+
get wrapperClasses() {
|
|
2068
|
+
const baseClasses = ['relative', 'w-full'];
|
|
2069
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
2070
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
2071
|
+
// Full bleed: scroll edge-to-edge en mobile
|
|
2072
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
2073
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
2074
|
+
}
|
|
2075
|
+
return [
|
|
2076
|
+
...baseClasses,
|
|
2077
|
+
...strategyClasses,
|
|
2078
|
+
...variantClasses,
|
|
2079
|
+
this.className
|
|
2080
|
+
].filter(Boolean);
|
|
2081
|
+
}
|
|
2082
|
+
get tableClasses() {
|
|
2083
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
2084
|
+
const variantClasses = this.getVariantTableClasses();
|
|
2085
|
+
const cellClasses = this.getCellClasses();
|
|
2086
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
2087
|
+
}
|
|
2088
|
+
getResponsiveStrategyClasses() {
|
|
2089
|
+
const strategy = TABLE_RESPONSIVE[this.responsiveStrategy];
|
|
2090
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2091
|
+
return ['overflow-x-auto'];
|
|
2092
|
+
}
|
|
2093
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2094
|
+
return ['overflow-x-auto'];
|
|
2095
|
+
}
|
|
2096
|
+
if (this.responsiveStrategy === 'stack') {
|
|
2097
|
+
// Stack requiere lógica en el template, aquí solo el wrapper
|
|
2098
|
+
return [];
|
|
2099
|
+
}
|
|
2100
|
+
if (this.responsiveStrategy === 'collapse') {
|
|
2101
|
+
return ['overflow-x-auto'];
|
|
2102
|
+
}
|
|
2103
|
+
return ['overflow-auto'];
|
|
2104
|
+
}
|
|
2105
|
+
getVariantWrapperClasses() {
|
|
2106
|
+
if (this.variant === 'interactive') {
|
|
2107
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
2108
|
+
}
|
|
2109
|
+
if (this.variant === 'data') {
|
|
2110
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
2111
|
+
}
|
|
2112
|
+
return [];
|
|
2113
|
+
}
|
|
2114
|
+
getVariantTableClasses() {
|
|
2115
|
+
if (this.variant === 'data') {
|
|
2116
|
+
return [
|
|
2117
|
+
'border-collapse',
|
|
2118
|
+
'text-foreground',
|
|
2119
|
+
'[&_thead_tr]:border-b',
|
|
2120
|
+
'[&_thead_tr]:border-border',
|
|
2121
|
+
'[&_tbody_tr]:border-b',
|
|
2122
|
+
'[&_tbody_tr]:border-border',
|
|
2123
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2124
|
+
'[&_th]:h-10',
|
|
2125
|
+
'[&_th]:px-2',
|
|
2126
|
+
'[&_th]:text-left',
|
|
2127
|
+
'[&_th]:align-middle',
|
|
2128
|
+
'[&_th]:font-medium',
|
|
2129
|
+
'[&_td]:p-2',
|
|
2130
|
+
'[&_td]:align-middle'
|
|
2131
|
+
];
|
|
2132
|
+
}
|
|
2133
|
+
if (this.variant === 'interactive') {
|
|
2134
|
+
return [
|
|
2135
|
+
'text-foreground',
|
|
2136
|
+
'[&_thead]:sticky',
|
|
2137
|
+
'[&_thead]:top-0',
|
|
2138
|
+
'[&_thead]:z-10',
|
|
2139
|
+
'[&_thead]:bg-muted/70',
|
|
2140
|
+
'[&_thead_tr]:border-b',
|
|
2141
|
+
'[&_thead_tr]:border-border',
|
|
2142
|
+
'[&_th]:h-12',
|
|
2143
|
+
'[&_th]:px-4',
|
|
2144
|
+
'[&_th]:text-left',
|
|
2145
|
+
'[&_th]:align-middle',
|
|
2146
|
+
'[&_th]:text-sm',
|
|
2147
|
+
'[&_th]:font-medium',
|
|
2148
|
+
'[&_tbody_tr]:border-b',
|
|
2149
|
+
'[&_tbody_tr]:border-border',
|
|
2150
|
+
'[&_tbody_tr]:transition-colors',
|
|
2151
|
+
'[&_tbody_tr:hover]:bg-muted/50',
|
|
2152
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
2153
|
+
'[&_td]:h-14',
|
|
2154
|
+
'[&_td]:px-4',
|
|
2155
|
+
'[&_td]:align-middle',
|
|
2156
|
+
'[&_td]:text-sm',
|
|
2157
|
+
'[&_svg]:text-muted-foreground'
|
|
2158
|
+
];
|
|
2159
|
+
}
|
|
2160
|
+
return [];
|
|
2161
|
+
}
|
|
2162
|
+
getCellClasses() {
|
|
2163
|
+
// Manejo responsive de whitespace
|
|
2164
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
2165
|
+
// En scroll, permitir wrap en mobile, nowrap en desktop
|
|
2166
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
2167
|
+
}
|
|
2168
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
2169
|
+
// En wrap, siempre permitir wrap
|
|
2170
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
2171
|
+
}
|
|
2172
|
+
// Default: nowrap (comportamiento anterior para backward compatibility)
|
|
2173
|
+
return [];
|
|
2174
|
+
}
|
|
2175
|
+
}
|
|
2176
|
+
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2177
|
+
PdmTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTableComponent, selector: "pdm-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed" }, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
2179
|
+
type: Component,
|
|
2180
|
+
args: [{ selector: 'pdm-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
|
|
2181
|
+
}], propDecorators: { variant: [{
|
|
2182
|
+
type: Input
|
|
2183
|
+
}], responsiveStrategy: [{
|
|
2184
|
+
type: Input
|
|
2185
|
+
}], className: [{
|
|
2186
|
+
type: Input
|
|
2187
|
+
}], fullBleed: [{
|
|
2188
|
+
type: Input
|
|
2189
|
+
}] } });
|
|
2190
|
+
|
|
2191
|
+
/**
|
|
2192
|
+
* Data-table genérico con paginación, filtrado y selección
|
|
2193
|
+
*
|
|
2194
|
+
* NUEVO: Ahora es genérico y configurable via columnas
|
|
2195
|
+
*
|
|
2196
|
+
* @example
|
|
2197
|
+
* // Definir columnas
|
|
2198
|
+
* columns: PdmDataTableColumn<User>[] = [
|
|
2199
|
+
* { key: 'name', label: 'Name', sortable: true },
|
|
2200
|
+
* { key: 'email', label: 'Email', sortable: true },
|
|
2201
|
+
* { key: 'role', label: 'Role', hideOnMobile: true },
|
|
2202
|
+
* { key: 'createdAt', label: 'Created', render: (val) => formatDate(val) }
|
|
2203
|
+
* ];
|
|
2204
|
+
*
|
|
2205
|
+
* // En el template
|
|
2206
|
+
* <pdm-data-table
|
|
2207
|
+
* [columns]="columns"
|
|
2208
|
+
* [rows]="users"
|
|
2209
|
+
* [selectable]="true"
|
|
2210
|
+
* (selectionChange)="onSelect($event)">
|
|
2211
|
+
* </pdm-data-table>
|
|
2212
|
+
*/
|
|
1837
2213
|
class PdmDataTableComponent {
|
|
1838
2214
|
constructor() {
|
|
1839
2215
|
this.className = '';
|
|
2216
|
+
/**
|
|
2217
|
+
* Columnas a mostrar
|
|
2218
|
+
* Si no se provee, intenta inferir del primer row (legacy mode)
|
|
2219
|
+
*/
|
|
2220
|
+
this.columns = [];
|
|
2221
|
+
/**
|
|
2222
|
+
* Estrategia responsive de la tabla
|
|
2223
|
+
*/
|
|
2224
|
+
this.responsiveStrategy = 'scroll';
|
|
2225
|
+
/**
|
|
2226
|
+
* Si es true, muestra checkbox de selección en cada fila
|
|
2227
|
+
*/
|
|
2228
|
+
this.selectable = false;
|
|
2229
|
+
/**
|
|
2230
|
+
* Si es true, muestra botón de acciones (tres puntos) en cada fila
|
|
2231
|
+
*/
|
|
2232
|
+
this.showActions = false;
|
|
2233
|
+
/**
|
|
2234
|
+
* Si es true, muestra filtro de búsqueda
|
|
2235
|
+
*/
|
|
2236
|
+
this.showFilter = true;
|
|
2237
|
+
/**
|
|
2238
|
+
* Si es true, muestra controles de paginación
|
|
2239
|
+
*/
|
|
2240
|
+
this.showPagination = true;
|
|
2241
|
+
/**
|
|
2242
|
+
* Si es true, muestra selector de columnas
|
|
2243
|
+
*/
|
|
2244
|
+
this.showColumnSelector = false;
|
|
2245
|
+
// Labels i18n
|
|
1840
2246
|
this.filterPlaceholder = 'Filter...';
|
|
1841
2247
|
this.columnsLabel = 'Columns';
|
|
1842
|
-
this.statusLabel = 'Status';
|
|
1843
|
-
this.emailLabel = 'Email';
|
|
1844
|
-
this.amountLabel = 'Amount';
|
|
1845
2248
|
this.previousLabel = 'Previous';
|
|
1846
2249
|
this.nextLabel = 'Next';
|
|
1847
2250
|
this.emptyLabel = 'No results.';
|
|
2251
|
+
this.rowsSelectedLabel = 'row(s) selected';
|
|
2252
|
+
// DEPRECATED: Labels hardcodeados para backward compatibility
|
|
2253
|
+
/**
|
|
2254
|
+
* @deprecated Use columns configuration instead
|
|
2255
|
+
*/
|
|
2256
|
+
this.statusLabel = 'Status';
|
|
2257
|
+
/**
|
|
2258
|
+
* @deprecated Use columns configuration instead
|
|
2259
|
+
*/
|
|
2260
|
+
this.emailLabel = 'Email';
|
|
2261
|
+
/**
|
|
2262
|
+
* @deprecated Use columns configuration instead
|
|
2263
|
+
*/
|
|
2264
|
+
this.amountLabel = 'Amount';
|
|
2265
|
+
/**
|
|
2266
|
+
* Datos a mostrar
|
|
2267
|
+
*/
|
|
1848
2268
|
this.rows = [];
|
|
2269
|
+
/**
|
|
2270
|
+
* Página actual (1-indexed)
|
|
2271
|
+
*/
|
|
1849
2272
|
this.page = 1;
|
|
1850
|
-
|
|
2273
|
+
/**
|
|
2274
|
+
* Cantidad de filas por página
|
|
2275
|
+
*/
|
|
2276
|
+
this.pageSize = 10;
|
|
2277
|
+
/**
|
|
2278
|
+
* Query de filtrado
|
|
2279
|
+
*/
|
|
1851
2280
|
this.query = '';
|
|
1852
2281
|
this.queryChange = new EventEmitter();
|
|
1853
2282
|
this.rowAction = new EventEmitter();
|
|
1854
2283
|
this.pageChange = new EventEmitter();
|
|
1855
2284
|
this.selectionChange = new EventEmitter();
|
|
2285
|
+
this.columnSort = new EventEmitter();
|
|
2286
|
+
// Estado interno
|
|
2287
|
+
this.selectedRows = new Set();
|
|
2288
|
+
this.sortDirection = 'asc';
|
|
2289
|
+
}
|
|
2290
|
+
/**
|
|
2291
|
+
* Backward compatibility: si no hay columnas definidas, inferir del primer row
|
|
2292
|
+
*/
|
|
2293
|
+
get effectiveColumns() {
|
|
2294
|
+
if (this.columns.length > 0) {
|
|
2295
|
+
return this.columns;
|
|
2296
|
+
}
|
|
2297
|
+
// Legacy mode: inferir columnas del primer row (solo para PdmDataTableRow)
|
|
2298
|
+
if (this.rows.length > 0) {
|
|
2299
|
+
const firstRow = this.rows[0];
|
|
2300
|
+
return Object.keys(firstRow)
|
|
2301
|
+
.filter(key => key !== 'selected')
|
|
2302
|
+
.map(key => ({
|
|
2303
|
+
key: key,
|
|
2304
|
+
label: this.getLegacyLabel(key),
|
|
2305
|
+
align: key === 'amount' ? 'right' : 'left'
|
|
2306
|
+
}));
|
|
2307
|
+
}
|
|
2308
|
+
return [];
|
|
2309
|
+
}
|
|
2310
|
+
/**
|
|
2311
|
+
* LEGACY: mapeo de keys a labels hardcodeados
|
|
2312
|
+
*/
|
|
2313
|
+
getLegacyLabel(key) {
|
|
2314
|
+
const map = {
|
|
2315
|
+
status: this.statusLabel,
|
|
2316
|
+
email: this.emailLabel,
|
|
2317
|
+
amount: this.amountLabel
|
|
2318
|
+
};
|
|
2319
|
+
return map[key] || key.charAt(0).toUpperCase() + key.slice(1);
|
|
1856
2320
|
}
|
|
1857
2321
|
get filteredRows() {
|
|
1858
2322
|
const q = this.query.trim().toLowerCase();
|
|
1859
2323
|
if (!q)
|
|
1860
2324
|
return this.rows;
|
|
1861
|
-
|
|
2325
|
+
if (this.filterFn) {
|
|
2326
|
+
return this.rows.filter(row => this.filterFn(row, q));
|
|
2327
|
+
}
|
|
2328
|
+
// Filtrado default: buscar en todos los campos string
|
|
2329
|
+
return this.rows.filter(row => {
|
|
2330
|
+
return Object.values(row).some(val => typeof val === 'string' && val.toLowerCase().includes(q));
|
|
2331
|
+
});
|
|
1862
2332
|
}
|
|
1863
2333
|
get pagedRows() {
|
|
1864
2334
|
const start = (this.page - 1) * this.pageSize;
|
|
@@ -1868,14 +2338,33 @@ class PdmDataTableComponent {
|
|
|
1868
2338
|
return Math.max(1, Math.ceil(this.filteredRows.length / this.pageSize));
|
|
1869
2339
|
}
|
|
1870
2340
|
get selectedCount() {
|
|
1871
|
-
return this.
|
|
2341
|
+
return this.selectedRows.size;
|
|
1872
2342
|
}
|
|
1873
2343
|
onQueryInput(event) {
|
|
1874
2344
|
const value = event.target.value;
|
|
1875
2345
|
this.queryChange.emit(value);
|
|
1876
2346
|
}
|
|
1877
2347
|
onToggleRow(row, event) {
|
|
1878
|
-
|
|
2348
|
+
const checked = event.target.checked;
|
|
2349
|
+
if (checked) {
|
|
2350
|
+
this.selectedRows.add(row);
|
|
2351
|
+
}
|
|
2352
|
+
else {
|
|
2353
|
+
this.selectedRows.delete(row);
|
|
2354
|
+
}
|
|
2355
|
+
this.selectionChange.emit({ row, selected: checked });
|
|
2356
|
+
}
|
|
2357
|
+
onToggleAll(event) {
|
|
2358
|
+
const checked = event.target.checked;
|
|
2359
|
+
if (checked) {
|
|
2360
|
+
this.pagedRows.forEach(row => this.selectedRows.add(row));
|
|
2361
|
+
}
|
|
2362
|
+
else {
|
|
2363
|
+
this.pagedRows.forEach(row => this.selectedRows.delete(row));
|
|
2364
|
+
}
|
|
2365
|
+
}
|
|
2366
|
+
isSelected(row) {
|
|
2367
|
+
return this.selectedRows.has(row);
|
|
1879
2368
|
}
|
|
1880
2369
|
previous() {
|
|
1881
2370
|
if (this.page <= 1)
|
|
@@ -1888,25 +2377,75 @@ class PdmDataTableComponent {
|
|
|
1888
2377
|
this.pageChange.emit(this.page + 1);
|
|
1889
2378
|
}
|
|
1890
2379
|
onAction(row) {
|
|
1891
|
-
this.rowAction.emit(row
|
|
2380
|
+
this.rowAction.emit(row);
|
|
2381
|
+
}
|
|
2382
|
+
onSort(column) {
|
|
2383
|
+
if (!column.sortable)
|
|
2384
|
+
return;
|
|
2385
|
+
if (this.sortColumn === column) {
|
|
2386
|
+
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
|
|
2387
|
+
}
|
|
2388
|
+
else {
|
|
2389
|
+
this.sortColumn = column;
|
|
2390
|
+
this.sortDirection = 'asc';
|
|
2391
|
+
}
|
|
2392
|
+
this.columnSort.emit({ column, direction: this.sortDirection });
|
|
2393
|
+
}
|
|
2394
|
+
getCellValue(row, column) {
|
|
2395
|
+
const value = row[column.key];
|
|
2396
|
+
if (column.render) {
|
|
2397
|
+
return column.render(value, row);
|
|
2398
|
+
}
|
|
2399
|
+
return value != null ? String(value) : '';
|
|
2400
|
+
}
|
|
2401
|
+
getCellClass(column) {
|
|
2402
|
+
const classes = ['px-2', 'py-2'];
|
|
2403
|
+
if (column.align === 'center')
|
|
2404
|
+
classes.push('text-center');
|
|
2405
|
+
if (column.align === 'right')
|
|
2406
|
+
classes.push('text-right');
|
|
2407
|
+
if (column.hideOnMobile)
|
|
2408
|
+
classes.push('hidden', 'md:table-cell');
|
|
2409
|
+
if (column.cellClass)
|
|
2410
|
+
classes.push(column.cellClass);
|
|
2411
|
+
return classes.join(' ');
|
|
2412
|
+
}
|
|
2413
|
+
getHeaderClass(column) {
|
|
2414
|
+
const classes = ['px-2', 'py-2', 'text-left', 'font-medium'];
|
|
2415
|
+
if (column.hideOnMobile)
|
|
2416
|
+
classes.push('hidden', 'md:table-cell');
|
|
2417
|
+
if (column.headerClass)
|
|
2418
|
+
classes.push(column.headerClass);
|
|
2419
|
+
return classes.join(' ');
|
|
2420
|
+
}
|
|
2421
|
+
getColumnStyle(column) {
|
|
2422
|
+
return column.width ? { width: column.width } : {};
|
|
1892
2423
|
}
|
|
1893
2424
|
}
|
|
1894
2425
|
PdmDataTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1895
|
-
PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className",
|
|
2426
|
+
PdmDataTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDataTableComponent, selector: "pdm-data-table", inputs: { className: "className", columns: "columns", responsiveStrategy: "responsiveStrategy", selectable: "selectable", showActions: "showActions", showFilter: "showFilter", showPagination: "showPagination", showColumnSelector: "showColumnSelector", filterPlaceholder: "filterPlaceholder", columnsLabel: "columnsLabel", previousLabel: "previousLabel", nextLabel: "nextLabel", emptyLabel: "emptyLabel", rowsSelectedLabel: "rowsSelectedLabel", statusLabel: "statusLabel", emailLabel: "emailLabel", amountLabel: "amountLabel", rows: "rows", page: "page", pageSize: "pageSize", query: "query", filterFn: "filterFn" }, outputs: { queryChange: "queryChange", rowAction: "rowAction", pageChange: "pageChange", selectionChange: "selectionChange", columnSort: "columnSort" }, ngImport: i0, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: PdmTableComponent, selector: "pdm-table", inputs: ["variant", "responsiveStrategy", "className", "fullBleed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
1896
2427
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDataTableComponent, decorators: [{
|
|
1897
2428
|
type: Component,
|
|
1898
|
-
args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full
|
|
2429
|
+
args: [{ selector: 'pdm-data-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<section [ngClass]=\"['flex w-full flex-col', className]\">\n <!-- Toolbar: Filtro + Selector de columnas -->\n <div *ngIf=\"showFilter || showColumnSelector\" class=\"flex w-full items-center justify-between gap-2 py-4\">\n <input\n *ngIf=\"showFilter\"\n type=\"text\"\n [placeholder]=\"filterPlaceholder\"\n [value]=\"query\"\n (input)=\"onQueryInput($event)\"\n class=\"h-9 flex-1 rounded-md border border-input bg-transparent px-3 py-1 text-sm text-foreground shadow-sm placeholder:text-muted-foreground outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\"\n />\n\n <button \n *ngIf=\"showColumnSelector\"\n type=\"button\" \n class=\"inline-flex h-9 appearance-none items-center gap-2 rounded-md border border-input bg-background px-3 py-2 text-sm font-medium text-foreground shadow-sm whitespace-nowrap\">\n <span>{{ columnsLabel }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4 text-foreground\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M7 10L12 15L17 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Tabla con responsive -->\n <pdm-table \n variant=\"data\"\n [responsiveStrategy]=\"responsiveStrategy\"\n [fullBleed]=\"false\">\n <thead>\n <tr>\n <!-- Columna de selecci\u00F3n -->\n <th *ngIf=\"selectable\" class=\"w-10 px-2 py-2 text-left font-medium\">\n <input \n type=\"checkbox\" \n (change)=\"onToggleAll($event)\"\n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </th>\n\n <!-- Columnas din\u00E1micas -->\n <th \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getHeaderClass(column)\"\n [ngStyle]=\"getColumnStyle(column)\">\n \n <!-- Header sortable -->\n <button \n *ngIf=\"column.sortable\"\n type=\"button\" \n (click)=\"onSort(column)\"\n class=\"inline-flex appearance-none items-center gap-1 rounded-sm border-0 bg-transparent px-3 py-2 text-sm hover:underline\">\n <span>{{ column.label }}</span>\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M8 6L4 10L8 14M16 18L20 14L16 10\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"></path>\n </svg>\n </button>\n\n <!-- Header no sortable -->\n <span *ngIf=\"!column.sortable\">{{ column.label }}</span>\n </th>\n\n <!-- Columna de acciones -->\n <th *ngIf=\"showActions\" class=\"w-10 px-2 py-2\"></th>\n </tr>\n </thead>\n\n <tbody>\n <!-- Filas con datos -->\n <tr *ngFor=\"let row of pagedRows\">\n <!-- Celda de selecci\u00F3n -->\n <td *ngIf=\"selectable\" class=\"px-2 py-2\">\n <input \n type=\"checkbox\" \n [checked]=\"isSelected(row)\" \n (change)=\"onToggleRow(row, $event)\" \n class=\"h-4 w-4 rounded-sm border border-input\" \n />\n </td>\n\n <!-- Celdas din\u00E1micas -->\n <td \n *ngFor=\"let column of effectiveColumns\"\n [ngClass]=\"getCellClass(column)\">\n \n <!-- Template personalizado si existe -->\n <ng-container *ngIf=\"column.cellTemplate; else defaultCell\">\n <ng-container \n *ngTemplateOutlet=\"column.cellTemplate; context: { $implicit: row, value: row[column.key] }\">\n </ng-container>\n </ng-container>\n\n <!-- Renderizado default -->\n <ng-template #defaultCell>\n {{ getCellValue(row, column) }}\n </ng-template>\n </td>\n\n <!-- Celda de acciones -->\n <td *ngIf=\"showActions\" class=\"px-2 py-2\">\n <button \n type=\"button\" \n class=\"inline-flex h-8 w-8 appearance-none items-center justify-center border-0 bg-transparent p-0 hover:text-foreground\" \n (click)=\"onAction(row)\">\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <circle cx=\"6\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"12\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n <circle cx=\"18\" cy=\"12\" r=\"1.5\" fill=\"currentColor\"></circle>\n </svg>\n </button>\n </td>\n </tr>\n\n <!-- Fila vac\u00EDa -->\n <tr *ngIf=\"pagedRows.length === 0\">\n <td \n [attr.colspan]=\"effectiveColumns.length + (selectable ? 1 : 0) + (showActions ? 1 : 0)\" \n class=\"px-3 py-6 text-center text-sm text-muted-foreground\">\n {{ emptyLabel }}\n </td>\n </tr>\n </tbody>\n </pdm-table>\n\n <!-- Footer: Info + Paginaci\u00F3n -->\n <div *ngIf=\"showPagination || selectable\" class=\"flex w-full items-center gap-2 py-4 flex-wrap sm:flex-nowrap\">\n <p *ngIf=\"selectable\" class=\"m-0 flex-1 pr-2 text-sm text-muted-foreground whitespace-nowrap\">\n {{ selectedCount }} of {{ rows.length }} {{ rowsSelectedLabel }}\n </p>\n\n <div *ngIf=\"showPagination\" class=\"flex items-center gap-2 ml-auto\">\n <span class=\"text-sm text-muted-foreground whitespace-nowrap\">\n Page {{ page }} of {{ totalPages }}\n </span>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page <= 1\" \n (click)=\"previous()\">\n {{ previousLabel }}\n </button>\n <button \n type=\"button\" \n class=\"h-9 appearance-none rounded-md border border-input bg-background px-4 text-sm font-medium text-foreground shadow-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed\" \n [disabled]=\"page >= totalPages\" \n (click)=\"next()\">\n {{ nextLabel }}\n </button>\n </div>\n </div>\n</section>\n" }]
|
|
1899
2430
|
}], propDecorators: { className: [{
|
|
1900
2431
|
type: Input
|
|
1901
|
-
}],
|
|
2432
|
+
}], columns: [{
|
|
1902
2433
|
type: Input
|
|
1903
|
-
}],
|
|
2434
|
+
}], responsiveStrategy: [{
|
|
1904
2435
|
type: Input
|
|
1905
|
-
}],
|
|
2436
|
+
}], selectable: [{
|
|
1906
2437
|
type: Input
|
|
1907
|
-
}],
|
|
2438
|
+
}], showActions: [{
|
|
1908
2439
|
type: Input
|
|
1909
|
-
}],
|
|
2440
|
+
}], showFilter: [{
|
|
2441
|
+
type: Input
|
|
2442
|
+
}], showPagination: [{
|
|
2443
|
+
type: Input
|
|
2444
|
+
}], showColumnSelector: [{
|
|
2445
|
+
type: Input
|
|
2446
|
+
}], filterPlaceholder: [{
|
|
2447
|
+
type: Input
|
|
2448
|
+
}], columnsLabel: [{
|
|
1910
2449
|
type: Input
|
|
1911
2450
|
}], previousLabel: [{
|
|
1912
2451
|
type: Input
|
|
@@ -1914,6 +2453,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1914
2453
|
type: Input
|
|
1915
2454
|
}], emptyLabel: [{
|
|
1916
2455
|
type: Input
|
|
2456
|
+
}], rowsSelectedLabel: [{
|
|
2457
|
+
type: Input
|
|
2458
|
+
}], statusLabel: [{
|
|
2459
|
+
type: Input
|
|
2460
|
+
}], emailLabel: [{
|
|
2461
|
+
type: Input
|
|
2462
|
+
}], amountLabel: [{
|
|
2463
|
+
type: Input
|
|
1917
2464
|
}], rows: [{
|
|
1918
2465
|
type: Input
|
|
1919
2466
|
}], page: [{
|
|
@@ -1922,6 +2469,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1922
2469
|
type: Input
|
|
1923
2470
|
}], query: [{
|
|
1924
2471
|
type: Input
|
|
2472
|
+
}], filterFn: [{
|
|
2473
|
+
type: Input
|
|
1925
2474
|
}], queryChange: [{
|
|
1926
2475
|
type: Output
|
|
1927
2476
|
}], rowAction: [{
|
|
@@ -1930,6 +2479,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
1930
2479
|
type: Output
|
|
1931
2480
|
}], selectionChange: [{
|
|
1932
2481
|
type: Output
|
|
2482
|
+
}], columnSort: [{
|
|
2483
|
+
type: Output
|
|
1933
2484
|
}] } });
|
|
1934
2485
|
|
|
1935
2486
|
/**
|
|
@@ -2347,13 +2898,135 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2347
2898
|
args: ['document:keydown.escape']
|
|
2348
2899
|
}] } });
|
|
2349
2900
|
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2901
|
+
/**
|
|
2902
|
+
* Z-Index Scale - Sistema centralizado de z-index
|
|
2903
|
+
*
|
|
2904
|
+
* JERARQUÍA (de menor a mayor):
|
|
2905
|
+
* 1. base (z-0) - Elementos normales del DOM
|
|
2906
|
+
* 2. dropdown (z-10) - Selects, combobox, date-pickers
|
|
2907
|
+
* 3. sticky (z-20) - Headers, navigation bars
|
|
2908
|
+
* 4. overlay (z-30) - Popovers, hover cards, context menus
|
|
2909
|
+
* 5. drawer (z-40) - Sidebar drawer, sheets laterales
|
|
2910
|
+
* 6. modal (z-50) - Dialogs, alert-dialogs
|
|
2911
|
+
* 7. modal-backdrop (z-40) - Backdrop de modals
|
|
2912
|
+
* 8. popover (z-60) - Tooltips, dropdowns DENTRO de modals
|
|
2913
|
+
* 9. toast (z-[100]) - Notificaciones que deben estar sobre TODO
|
|
2914
|
+
*
|
|
2915
|
+
* REGLA CRÍTICA:
|
|
2916
|
+
* - Componentes overlay (select options, dropdown menu, tooltip) SIEMPRE z-60 o mayor
|
|
2917
|
+
* - Esto permite que funcionen DENTRO de modals (z-50)
|
|
2918
|
+
* - Backdrop de modal debe ser z-40 para estar DEBAJO del contenido del modal (z-50)
|
|
2919
|
+
*/
|
|
2920
|
+
const Z_INDEX = {
|
|
2921
|
+
/**
|
|
2922
|
+
* Base - contenido normal del DOM
|
|
2923
|
+
*/
|
|
2924
|
+
base: 'z-0',
|
|
2925
|
+
/**
|
|
2926
|
+
* Dropdown - Selects, combobox, date-pickers
|
|
2927
|
+
* Debe estar SOBRE contenido normal pero BAJO modals
|
|
2928
|
+
*/
|
|
2929
|
+
dropdown: 'z-10',
|
|
2930
|
+
/**
|
|
2931
|
+
* Sticky - Headers, navigation fija
|
|
2932
|
+
*/
|
|
2933
|
+
sticky: 'z-20',
|
|
2934
|
+
/**
|
|
2935
|
+
* Overlay - Popovers, hover cards, context menus
|
|
2936
|
+
* Debe estar SOBRE sticky pero BAJO modals
|
|
2937
|
+
*/
|
|
2938
|
+
overlay: 'z-30',
|
|
2939
|
+
/**
|
|
2940
|
+
* Drawer backdrop - Backdrop de sidebar drawer
|
|
2941
|
+
* Debe estar DEBAJO del drawer panel
|
|
2942
|
+
*/
|
|
2943
|
+
drawerBackdrop: 'z-40',
|
|
2944
|
+
/**
|
|
2945
|
+
* Drawer - Sidebar drawer, sheets laterales
|
|
2946
|
+
* Debe estar SOBRE su backdrop pero BAJO modals
|
|
2947
|
+
*/
|
|
2948
|
+
drawer: 'z-50',
|
|
2949
|
+
/**
|
|
2950
|
+
* Modal backdrop - Backdrop de dialogs
|
|
2951
|
+
* Debe estar SOBRE drawers pero DEBAJO del contenido del modal
|
|
2952
|
+
*/
|
|
2953
|
+
modalBackdrop: 'z-50',
|
|
2954
|
+
/**
|
|
2955
|
+
* Modal - Dialogs, alert-dialogs, sheets
|
|
2956
|
+
* Debe estar SOBRE su backdrop
|
|
2957
|
+
*/
|
|
2958
|
+
modal: 'z-[60]',
|
|
2959
|
+
/**
|
|
2960
|
+
* Popover - Tooltips, dropdowns, selects options DENTRO de modals
|
|
2961
|
+
* CRÍTICO: Debe ser MAYOR que modal (z-50) para aparecer sobre modals
|
|
2962
|
+
*/
|
|
2963
|
+
popover: 'z-[70]',
|
|
2964
|
+
/**
|
|
2965
|
+
* Toast - Notificaciones globales
|
|
2966
|
+
* Debe estar sobre TODO
|
|
2967
|
+
*/
|
|
2968
|
+
toast: 'z-[100]'
|
|
2969
|
+
};
|
|
2970
|
+
/**
|
|
2971
|
+
* Helper para debugging z-index issues
|
|
2972
|
+
*/
|
|
2973
|
+
function logZIndexStack(element) {
|
|
2974
|
+
if (typeof window === 'undefined')
|
|
2975
|
+
return;
|
|
2976
|
+
let current = element;
|
|
2977
|
+
const stack = [];
|
|
2978
|
+
while (current && current !== document.body) {
|
|
2979
|
+
const computed = window.getComputedStyle(current);
|
|
2980
|
+
const zIndex = computed.zIndex;
|
|
2981
|
+
const position = computed.position;
|
|
2982
|
+
if (zIndex !== 'auto') {
|
|
2983
|
+
stack.push({
|
|
2984
|
+
element: current.tagName + (current.className ? `.${current.className.split(' ')[0]}` : ''),
|
|
2985
|
+
zIndex,
|
|
2986
|
+
position
|
|
2987
|
+
});
|
|
2988
|
+
}
|
|
2989
|
+
current = current.parentElement;
|
|
2990
|
+
}
|
|
2991
|
+
console.table(stack);
|
|
2992
|
+
}
|
|
2993
|
+
|
|
2994
|
+
/**
|
|
2995
|
+
* Modal/Dialog component con soporte responsive
|
|
2996
|
+
*
|
|
2997
|
+
* MEJORADO en v0.2.0:
|
|
2998
|
+
* - Modo 'responsive' (default): fullscreen en mobile, modal en desktop
|
|
2999
|
+
* - Tamaños predefinidos: sm, md, lg, xl
|
|
3000
|
+
* - Mejor manejo de scroll en mobile
|
|
3001
|
+
*
|
|
3002
|
+
* @example
|
|
3003
|
+
* // Responsive (recomendado)
|
|
3004
|
+
* <pdm-dialog [open]="isOpen" size="responsive">
|
|
3005
|
+
* <p>Content</p>
|
|
3006
|
+
* </pdm-dialog>
|
|
3007
|
+
*
|
|
3008
|
+
* @example
|
|
3009
|
+
* // Tamaño fijo
|
|
3010
|
+
* <pdm-dialog [open]="isOpen" size="lg">
|
|
3011
|
+
* <p>Content</p>
|
|
3012
|
+
* </pdm-dialog>
|
|
3013
|
+
*/
|
|
3014
|
+
class PdmDialogComponent {
|
|
3015
|
+
constructor() {
|
|
3016
|
+
this.open = false;
|
|
3017
|
+
this.variant = 'default';
|
|
3018
|
+
/**
|
|
3019
|
+
* Tamaño del dialog
|
|
3020
|
+
* - responsive: fullscreen mobile, modal desktop (recomendado)
|
|
3021
|
+
* - sm: 400px max
|
|
3022
|
+
* - md: 500px max
|
|
3023
|
+
* - lg: 640px max (default)
|
|
3024
|
+
* - xl: 800px max
|
|
3025
|
+
* - desktop/mobile/mobile-fullscreen: legacy, deprecado
|
|
3026
|
+
*/
|
|
3027
|
+
this.size = 'responsive';
|
|
3028
|
+
this.title = 'Edit profile';
|
|
3029
|
+
this.description = '';
|
|
2357
3030
|
this.closeOnBackdrop = true;
|
|
2358
3031
|
this.closeOnEsc = true;
|
|
2359
3032
|
this.showCloseButton = true;
|
|
@@ -2390,47 +3063,132 @@ class PdmDialogComponent {
|
|
|
2390
3063
|
}
|
|
2391
3064
|
}
|
|
2392
3065
|
get panelClassName() {
|
|
3066
|
+
// Legacy sizes (backward compatibility)
|
|
3067
|
+
if (this.size === 'desktop') {
|
|
3068
|
+
return this.buildClasses(['max-w-[640px]', 'max-h-[calc(100vh-2rem)]', 'rounded-[10px]']);
|
|
3069
|
+
}
|
|
3070
|
+
if (this.size === 'mobile') {
|
|
3071
|
+
return this.buildClasses(['max-w-[320px]', 'min-h-[240px]', 'rounded-[10px]']);
|
|
3072
|
+
}
|
|
3073
|
+
if (this.size === 'mobile-fullscreen') {
|
|
3074
|
+
return this.buildClasses(['max-w-[320px]', 'h-[min(100dvh,640px)]', 'rounded-none', 'sm:rounded-[10px]']);
|
|
3075
|
+
}
|
|
3076
|
+
// New responsive mode (recomendado)
|
|
3077
|
+
if (this.size === 'responsive') {
|
|
3078
|
+
return this.buildClasses([
|
|
3079
|
+
// Mobile: fullscreen con bordes redondeados solo arriba
|
|
3080
|
+
'w-full',
|
|
3081
|
+
'h-full',
|
|
3082
|
+
'max-h-[100dvh]',
|
|
3083
|
+
'rounded-t-[10px]',
|
|
3084
|
+
'sm:rounded-[10px]',
|
|
3085
|
+
// Desktop: modal centrado
|
|
3086
|
+
'sm:w-auto',
|
|
3087
|
+
'sm:h-auto',
|
|
3088
|
+
'sm:max-w-[640px]',
|
|
3089
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3090
|
+
]);
|
|
3091
|
+
}
|
|
3092
|
+
// New size options
|
|
3093
|
+
const sizeMap = {
|
|
3094
|
+
sm: 'sm:max-w-[400px]',
|
|
3095
|
+
md: 'sm:max-w-[500px]',
|
|
3096
|
+
lg: 'sm:max-w-[640px]',
|
|
3097
|
+
xl: 'sm:max-w-[800px]'
|
|
3098
|
+
};
|
|
3099
|
+
const maxWidth = sizeMap[this.size] || sizeMap.lg;
|
|
3100
|
+
return this.buildClasses([
|
|
3101
|
+
// Mobile: fullscreen
|
|
3102
|
+
'w-full',
|
|
3103
|
+
'h-full',
|
|
3104
|
+
'max-h-[100dvh]',
|
|
3105
|
+
'rounded-t-[10px]',
|
|
3106
|
+
// Desktop: modal
|
|
3107
|
+
'sm:rounded-[10px]',
|
|
3108
|
+
'sm:w-auto',
|
|
3109
|
+
'sm:h-auto',
|
|
3110
|
+
maxWidth,
|
|
3111
|
+
'sm:max-h-[calc(100vh-4rem)]'
|
|
3112
|
+
]);
|
|
3113
|
+
}
|
|
3114
|
+
buildClasses(sizeClasses) {
|
|
2393
3115
|
const base = [
|
|
2394
|
-
'relative
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
3116
|
+
'relative',
|
|
3117
|
+
Z_INDEX.modal,
|
|
3118
|
+
'flex',
|
|
3119
|
+
'flex-col',
|
|
3120
|
+
'border',
|
|
3121
|
+
'border-border',
|
|
3122
|
+
'bg-background',
|
|
3123
|
+
'text-foreground',
|
|
3124
|
+
'shadow-lg',
|
|
3125
|
+
'overflow-hidden',
|
|
3126
|
+
...sizeClasses,
|
|
2400
3127
|
this.className
|
|
2401
3128
|
];
|
|
2402
3129
|
return base.filter(Boolean).join(' ');
|
|
2403
3130
|
}
|
|
2404
3131
|
get bodyWrapperClassName() {
|
|
2405
3132
|
const base = [
|
|
2406
|
-
'
|
|
2407
|
-
|
|
3133
|
+
'flex-1',
|
|
3134
|
+
'overflow-y-auto',
|
|
3135
|
+
'px-4',
|
|
3136
|
+
'py-6',
|
|
3137
|
+
'sm:px-6',
|
|
2408
3138
|
this.bodyClassName
|
|
2409
3139
|
];
|
|
2410
3140
|
return base.filter(Boolean).join(' ');
|
|
2411
3141
|
}
|
|
2412
3142
|
get headerWrapperClassName() {
|
|
2413
|
-
|
|
3143
|
+
const base = [
|
|
3144
|
+
'flex',
|
|
3145
|
+
'items-start',
|
|
3146
|
+
'justify-between',
|
|
3147
|
+
'gap-3',
|
|
3148
|
+
'p-4',
|
|
3149
|
+
'sm:p-6',
|
|
3150
|
+
'border-b',
|
|
3151
|
+
'border-border',
|
|
3152
|
+
this.headerClassName
|
|
3153
|
+
];
|
|
3154
|
+
return base.filter(Boolean).join(' ');
|
|
2414
3155
|
}
|
|
2415
3156
|
get footerWrapperClassName() {
|
|
2416
3157
|
const effectiveAlign = this.alignFooter === 'right' && this.variant === 'custom-close' ? 'left' : this.alignFooter;
|
|
2417
3158
|
const base = [
|
|
2418
3159
|
'p-4',
|
|
3160
|
+
'sm:p-6',
|
|
3161
|
+
'border-t',
|
|
3162
|
+
'border-border',
|
|
3163
|
+
// Mobile: siempre full-width
|
|
3164
|
+
'flex',
|
|
3165
|
+
'flex-col',
|
|
3166
|
+
'gap-2',
|
|
3167
|
+
// Desktop: según alignFooter
|
|
2419
3168
|
effectiveAlign === 'full-width'
|
|
2420
|
-
? 'flex
|
|
2421
|
-
:
|
|
2422
|
-
|
|
2423
|
-
|
|
3169
|
+
? 'sm:flex-col'
|
|
3170
|
+
: 'sm:flex-row sm:items-center',
|
|
3171
|
+
effectiveAlign === 'left' ? 'sm:justify-start' : '',
|
|
3172
|
+
effectiveAlign === 'right' ? 'sm:justify-end' : '',
|
|
2424
3173
|
this.footerClassName
|
|
2425
3174
|
];
|
|
2426
3175
|
return base.filter(Boolean).join(' ');
|
|
2427
3176
|
}
|
|
3177
|
+
get containerClassName() {
|
|
3178
|
+
// Container con backdrop z-50
|
|
3179
|
+
// Mobile: fullscreen desde el bottom
|
|
3180
|
+
// Desktop: centrado
|
|
3181
|
+
return responsive({
|
|
3182
|
+
default: `fixed inset-x-0 bottom-0 ${Z_INDEX.modalBackdrop} flex items-end justify-center`,
|
|
3183
|
+
sm: `fixed inset-0 ${Z_INDEX.modalBackdrop} flex items-center justify-center p-4`
|
|
3184
|
+
});
|
|
3185
|
+
}
|
|
2428
3186
|
}
|
|
2429
3187
|
PdmDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2430
|
-
PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\"
|
|
3188
|
+
PdmDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDialogComponent, selector: "pdm-dialog", inputs: { open: "open", variant: "variant", size: "size", title: "title", description: "description", closeOnBackdrop: "closeOnBackdrop", closeOnEsc: "closeOnEsc", showCloseButton: "showCloseButton", showHeader: "showHeader", showFooter: "showFooter", primaryActionText: "primaryActionText", secondaryActionText: "secondaryActionText", alignFooter: "alignFooter", headerClassName: "headerClassName", bodyClassName: "bodyClassName", footerClassName: "footerClassName", className: "className" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2431
3189
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDialogComponent, decorators: [{
|
|
2432
3190
|
type: Component,
|
|
2433
|
-
args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3191
|
+
args: [{ selector: 'pdm-dialog', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n \n <!-- Dialog Panel -->\n <section role=\"dialog\" aria-modal=\"true\" [ngClass]=\"panelClassName\">\n <!-- Header -->\n <div *ngIf=\"showHeader\" [ngClass]=\"headerWrapperClassName\">\n <div class=\"min-w-0 flex-1\">\n <h2 class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">{{ title }}</h2>\n <p *ngIf=\"description\" class=\"m-0 mt-2 text-sm text-muted-foreground\">{{ description }}</p>\n </div>\n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\"\n (click)=\"close()\"\n aria-label=\"Close dialog\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Body -->\n <div [ngClass]=\"bodyWrapperClassName\">\n <ng-content></ng-content>\n </div>\n\n <!-- Footer -->\n <div *ngIf=\"showFooter\" [ngClass]=\"footerWrapperClassName\">\n <ng-container *ngIf=\"variant === 'custom-close'; else defaultActions\">\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n </ng-container>\n\n <ng-template #defaultActions>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md border border-input bg-background px-4 py-2 text-sm font-medium text-foreground shadow-sm sm:w-auto\"\n (click)=\"onSecondaryAction()\"\n >\n {{ secondaryActionText }}\n </button>\n <button\n type=\"button\"\n class=\"inline-flex h-9 w-full appearance-none items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-sm sm:w-auto\"\n (click)=\"onPrimaryAction()\"\n >\n {{ primaryActionText }}\n </button>\n </ng-template>\n </div>\n </section>\n</div>\n" }]
|
|
2434
3192
|
}], propDecorators: { open: [{
|
|
2435
3193
|
type: Input
|
|
2436
3194
|
}], variant: [{
|
|
@@ -2476,6 +3234,303 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2476
3234
|
args: ['document:keydown.escape']
|
|
2477
3235
|
}] } });
|
|
2478
3236
|
|
|
3237
|
+
/**
|
|
3238
|
+
* Tabla con funcionalidad de reordenamiento de filas mediante drag & drop
|
|
3239
|
+
*
|
|
3240
|
+
* Extiende pdm-table agregando la capacidad de reordenar filas.
|
|
3241
|
+
* Si no necesitás drag & drop, usá pdm-table directamente (más simple y liviano).
|
|
3242
|
+
*
|
|
3243
|
+
* @example
|
|
3244
|
+
* <pdm-draggable-table
|
|
3245
|
+
* variant="interactive"
|
|
3246
|
+
* [reorderRows]="true"
|
|
3247
|
+
* (rowOrderChange)="onOrderChange($event)">
|
|
3248
|
+
* <tbody>
|
|
3249
|
+
* <tr data-row-id="1"><td>Row 1</td></tr>
|
|
3250
|
+
* <tr data-row-id="2"><td>Row 2</td></tr>
|
|
3251
|
+
* </tbody>
|
|
3252
|
+
* </pdm-draggable-table>
|
|
3253
|
+
*
|
|
3254
|
+
* IMPORTANTE: Cada <tr> debe tener un atributo data-row-id único
|
|
3255
|
+
*/
|
|
3256
|
+
class PdmDraggableTableComponent {
|
|
3257
|
+
constructor(renderer) {
|
|
3258
|
+
this.renderer = renderer;
|
|
3259
|
+
this.variant = 'default';
|
|
3260
|
+
this.responsiveStrategy = 'scroll';
|
|
3261
|
+
this.className = '';
|
|
3262
|
+
this.fullBleed = false;
|
|
3263
|
+
/**
|
|
3264
|
+
* Habilita el reordenamiento de filas mediante drag & drop
|
|
3265
|
+
*/
|
|
3266
|
+
this.reorderRows = false;
|
|
3267
|
+
/**
|
|
3268
|
+
* Selector CSS para identificar los handles de drag
|
|
3269
|
+
* Por defecto busca: [data-drag-handle], [data-slot=row-drag-handle], .row-drag-handle
|
|
3270
|
+
* Si no encuentra ninguno, inserta un handle automático
|
|
3271
|
+
*/
|
|
3272
|
+
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
3273
|
+
/**
|
|
3274
|
+
* Emite el nuevo orden de las filas cuando el usuario termina de arrastrar
|
|
3275
|
+
* Array de data-row-id en el nuevo orden
|
|
3276
|
+
*/
|
|
3277
|
+
this.rowOrderChange = new EventEmitter();
|
|
3278
|
+
this.cleanupListeners = [];
|
|
3279
|
+
this.draggedRow = null;
|
|
3280
|
+
}
|
|
3281
|
+
ngAfterViewInit() {
|
|
3282
|
+
this.syncReorderBehavior();
|
|
3283
|
+
}
|
|
3284
|
+
// Getters para clases CSS (mismo comportamiento que pdm-table)
|
|
3285
|
+
get wrapperClasses() {
|
|
3286
|
+
const baseClasses = ['relative', 'w-full'];
|
|
3287
|
+
const strategyClasses = this.getResponsiveStrategyClasses();
|
|
3288
|
+
const variantClasses = this.getVariantWrapperClasses();
|
|
3289
|
+
if (this.fullBleed && this.responsiveStrategy === 'scroll') {
|
|
3290
|
+
baseClasses.push('-mx-4', 'px-4', 'sm:mx-0', 'sm:px-0');
|
|
3291
|
+
}
|
|
3292
|
+
return [
|
|
3293
|
+
...baseClasses,
|
|
3294
|
+
...strategyClasses,
|
|
3295
|
+
...variantClasses,
|
|
3296
|
+
this.className
|
|
3297
|
+
].filter(Boolean);
|
|
3298
|
+
}
|
|
3299
|
+
get tableClasses() {
|
|
3300
|
+
const baseClasses = ['w-full', 'caption-bottom', 'text-sm'];
|
|
3301
|
+
const variantClasses = this.getVariantTableClasses();
|
|
3302
|
+
const cellClasses = this.getCellClasses();
|
|
3303
|
+
return [...baseClasses, ...variantClasses, ...cellClasses].filter(Boolean);
|
|
3304
|
+
}
|
|
3305
|
+
getResponsiveStrategyClasses() {
|
|
3306
|
+
if (this.responsiveStrategy === 'scroll' || this.responsiveStrategy === 'wrap' || this.responsiveStrategy === 'collapse') {
|
|
3307
|
+
return ['overflow-x-auto'];
|
|
3308
|
+
}
|
|
3309
|
+
return [];
|
|
3310
|
+
}
|
|
3311
|
+
getVariantWrapperClasses() {
|
|
3312
|
+
if (this.variant === 'interactive') {
|
|
3313
|
+
return ['rounded-xl', 'border', 'border-border', 'bg-background'];
|
|
3314
|
+
}
|
|
3315
|
+
if (this.variant === 'data') {
|
|
3316
|
+
return ['rounded-md', 'border', 'border-border', 'bg-background'];
|
|
3317
|
+
}
|
|
3318
|
+
return [];
|
|
3319
|
+
}
|
|
3320
|
+
getVariantTableClasses() {
|
|
3321
|
+
if (this.variant === 'data') {
|
|
3322
|
+
return [
|
|
3323
|
+
'border-collapse', 'text-foreground',
|
|
3324
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3325
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3326
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3327
|
+
'[&_th]:h-10', '[&_th]:px-2', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:font-medium',
|
|
3328
|
+
'[&_td]:p-2', '[&_td]:align-middle'
|
|
3329
|
+
];
|
|
3330
|
+
}
|
|
3331
|
+
if (this.variant === 'interactive') {
|
|
3332
|
+
return [
|
|
3333
|
+
'text-foreground',
|
|
3334
|
+
'[&_thead]:sticky', '[&_thead]:top-0', '[&_thead]:z-10', '[&_thead]:bg-muted/70',
|
|
3335
|
+
'[&_thead_tr]:border-b', '[&_thead_tr]:border-border',
|
|
3336
|
+
'[&_th]:h-12', '[&_th]:px-4', '[&_th]:text-left', '[&_th]:align-middle', '[&_th]:text-sm', '[&_th]:font-medium',
|
|
3337
|
+
'[&_tbody_tr]:border-b', '[&_tbody_tr]:border-border',
|
|
3338
|
+
'[&_tbody_tr]:transition-colors', '[&_tbody_tr:hover]:bg-muted/50',
|
|
3339
|
+
'[&_tbody_tr:last-child]:border-b-0',
|
|
3340
|
+
'[&_td]:h-14', '[&_td]:px-4', '[&_td]:align-middle', '[&_td]:text-sm',
|
|
3341
|
+
'[&_svg]:text-muted-foreground'
|
|
3342
|
+
];
|
|
3343
|
+
}
|
|
3344
|
+
return [];
|
|
3345
|
+
}
|
|
3346
|
+
getCellClasses() {
|
|
3347
|
+
if (this.responsiveStrategy === 'scroll') {
|
|
3348
|
+
return ['[&_td]:whitespace-normal', '[&_th]:whitespace-normal', 'sm:[&_td]:whitespace-nowrap', 'sm:[&_th]:whitespace-nowrap'];
|
|
3349
|
+
}
|
|
3350
|
+
if (this.responsiveStrategy === 'wrap') {
|
|
3351
|
+
return ['[&_td]:whitespace-normal', '[&_td]:break-words', '[&_th]:whitespace-normal'];
|
|
3352
|
+
}
|
|
3353
|
+
return [];
|
|
3354
|
+
}
|
|
3355
|
+
ngOnChanges(changes) {
|
|
3356
|
+
if (changes['reorderRows'] || changes['variant']) {
|
|
3357
|
+
this.syncReorderBehavior();
|
|
3358
|
+
}
|
|
3359
|
+
}
|
|
3360
|
+
ngOnDestroy() {
|
|
3361
|
+
this.cleanupReorderBehavior();
|
|
3362
|
+
}
|
|
3363
|
+
syncReorderBehavior() {
|
|
3364
|
+
this.cleanupReorderBehavior();
|
|
3365
|
+
if (!this.reorderRows) {
|
|
3366
|
+
return;
|
|
3367
|
+
}
|
|
3368
|
+
const tbody = this.getTbody();
|
|
3369
|
+
if (!tbody) {
|
|
3370
|
+
return;
|
|
3371
|
+
}
|
|
3372
|
+
this.setRowsDraggable(tbody, true);
|
|
3373
|
+
this.cleanupListeners.push(this.renderer.listen(tbody, 'mousedown', (event) => this.armDragFromHandle(event)), this.renderer.listen(tbody, 'dragstart', (event) => this.onDragStart(event)), this.renderer.listen(tbody, 'dragover', (event) => this.onDragOver(event, tbody)), this.renderer.listen(tbody, 'drop', (event) => this.onDrop(event)), this.renderer.listen(tbody, 'dragend', () => this.onDragEnd()));
|
|
3374
|
+
// Observer para detectar cambios en el DOM (filas agregadas/removidas)
|
|
3375
|
+
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
3376
|
+
this.observer.observe(tbody, { childList: true });
|
|
3377
|
+
}
|
|
3378
|
+
cleanupReorderBehavior() {
|
|
3379
|
+
this.cleanupListeners.forEach((dispose) => dispose());
|
|
3380
|
+
this.cleanupListeners = [];
|
|
3381
|
+
if (this.observer) {
|
|
3382
|
+
this.observer.disconnect();
|
|
3383
|
+
this.observer = undefined;
|
|
3384
|
+
}
|
|
3385
|
+
const tbody = this.getTbody();
|
|
3386
|
+
if (tbody) {
|
|
3387
|
+
this.setRowsDraggable(tbody, false);
|
|
3388
|
+
}
|
|
3389
|
+
this.draggedRow = null;
|
|
3390
|
+
}
|
|
3391
|
+
getTbody() {
|
|
3392
|
+
return this.tableElement?.nativeElement.tBodies.item(0) ?? null;
|
|
3393
|
+
}
|
|
3394
|
+
setRowsDraggable(tbody, enabled) {
|
|
3395
|
+
const rows = Array.from(tbody.rows);
|
|
3396
|
+
rows.forEach((row) => {
|
|
3397
|
+
this.syncAutoDragHandle(row, enabled);
|
|
3398
|
+
row.draggable = false;
|
|
3399
|
+
if (!enabled) {
|
|
3400
|
+
delete row.dataset['dragging'];
|
|
3401
|
+
delete row.dataset['dragArmed'];
|
|
3402
|
+
}
|
|
3403
|
+
});
|
|
3404
|
+
}
|
|
3405
|
+
/**
|
|
3406
|
+
* Inserta un handle de drag automático si no existe uno custom
|
|
3407
|
+
*/
|
|
3408
|
+
syncAutoDragHandle(row, enabled) {
|
|
3409
|
+
const firstCell = row.cells.item(0);
|
|
3410
|
+
if (!firstCell) {
|
|
3411
|
+
return;
|
|
3412
|
+
}
|
|
3413
|
+
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
3414
|
+
if (!enabled) {
|
|
3415
|
+
existingAutoHandle?.remove();
|
|
3416
|
+
return;
|
|
3417
|
+
}
|
|
3418
|
+
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
3419
|
+
if (hasCustomHandle || existingAutoHandle) {
|
|
3420
|
+
return;
|
|
3421
|
+
}
|
|
3422
|
+
// Crear handle automático
|
|
3423
|
+
const button = this.renderer.createElement('button');
|
|
3424
|
+
this.renderer.setAttribute(button, 'type', 'button');
|
|
3425
|
+
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
3426
|
+
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
3427
|
+
this.renderer.addClass(button, 'inline-flex');
|
|
3428
|
+
this.renderer.addClass(button, 'h-7');
|
|
3429
|
+
this.renderer.addClass(button, 'w-7');
|
|
3430
|
+
this.renderer.addClass(button, 'items-center');
|
|
3431
|
+
this.renderer.addClass(button, 'justify-center');
|
|
3432
|
+
this.renderer.addClass(button, 'cursor-grab');
|
|
3433
|
+
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
3434
|
+
this.renderer.addClass(button, 'text-muted-foreground');
|
|
3435
|
+
const dots = this.renderer.createElement('span');
|
|
3436
|
+
this.renderer.addClass(dots, 'text-sm');
|
|
3437
|
+
this.renderer.addClass(dots, 'leading-none');
|
|
3438
|
+
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
3439
|
+
this.renderer.appendChild(button, dots);
|
|
3440
|
+
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
3441
|
+
}
|
|
3442
|
+
onDragStart(event) {
|
|
3443
|
+
const target = event.target;
|
|
3444
|
+
const row = target?.closest('tr');
|
|
3445
|
+
if (!row) {
|
|
3446
|
+
return;
|
|
3447
|
+
}
|
|
3448
|
+
const handle = target?.closest(this.dragHandleSelector);
|
|
3449
|
+
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
3450
|
+
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
3451
|
+
event.preventDefault();
|
|
3452
|
+
return;
|
|
3453
|
+
}
|
|
3454
|
+
this.draggedRow = row;
|
|
3455
|
+
this.draggedRow.dataset['dragging'] = 'true';
|
|
3456
|
+
if (event.dataTransfer) {
|
|
3457
|
+
event.dataTransfer.effectAllowed = 'move';
|
|
3458
|
+
event.dataTransfer.setData('text/plain', '');
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
onDragOver(event, tbody) {
|
|
3462
|
+
if (!this.draggedRow) {
|
|
3463
|
+
return;
|
|
3464
|
+
}
|
|
3465
|
+
event.preventDefault();
|
|
3466
|
+
const target = event.target;
|
|
3467
|
+
const targetRow = target?.closest('tr');
|
|
3468
|
+
if (!targetRow || targetRow === this.draggedRow) {
|
|
3469
|
+
return;
|
|
3470
|
+
}
|
|
3471
|
+
const rect = targetRow.getBoundingClientRect();
|
|
3472
|
+
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
3473
|
+
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
3474
|
+
}
|
|
3475
|
+
onDrop(event) {
|
|
3476
|
+
event.preventDefault();
|
|
3477
|
+
}
|
|
3478
|
+
onDragEnd() {
|
|
3479
|
+
const tbody = this.getTbody();
|
|
3480
|
+
if (tbody) {
|
|
3481
|
+
Array.from(tbody.rows).forEach((row) => {
|
|
3482
|
+
row.draggable = false;
|
|
3483
|
+
delete row.dataset['dragArmed'];
|
|
3484
|
+
});
|
|
3485
|
+
}
|
|
3486
|
+
if (this.draggedRow) {
|
|
3487
|
+
delete this.draggedRow.dataset['dragging'];
|
|
3488
|
+
this.draggedRow = null;
|
|
3489
|
+
}
|
|
3490
|
+
if (!tbody) {
|
|
3491
|
+
return;
|
|
3492
|
+
}
|
|
3493
|
+
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
3494
|
+
this.rowOrderChange.emit(order);
|
|
3495
|
+
}
|
|
3496
|
+
armDragFromHandle(event) {
|
|
3497
|
+
const target = event.target;
|
|
3498
|
+
const handle = target?.closest(this.dragHandleSelector);
|
|
3499
|
+
if (!handle) {
|
|
3500
|
+
return;
|
|
3501
|
+
}
|
|
3502
|
+
const row = handle.closest('tr');
|
|
3503
|
+
if (!row) {
|
|
3504
|
+
return;
|
|
3505
|
+
}
|
|
3506
|
+
row.draggable = true;
|
|
3507
|
+
row.dataset['dragArmed'] = 'true';
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
PdmDraggableTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
3511
|
+
PdmDraggableTableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDraggableTableComponent, selector: "pdm-draggable-table", inputs: { variant: "variant", responsiveStrategy: "responsiveStrategy", className: "className", fullBleed: "fullBleed", reorderRows: "reorderRows", dragHandleSelector: "dragHandleSelector" }, outputs: { rowOrderChange: "rowOrderChange" }, viewQueries: [{ propertyName: "tableElement", first: true, predicate: ["tableElement"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3512
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDraggableTableComponent, decorators: [{
|
|
3513
|
+
type: Component,
|
|
3514
|
+
args: [{ selector: 'pdm-draggable-table', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"wrapperClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table-container' : null\">\n <table #tableElement [ngClass]=\"tableClasses\" [attr.data-slot]=\"variant === 'interactive' ? 'table' : null\">\n <ng-content></ng-content>\n </table>\n</div>\n" }]
|
|
3515
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
3516
|
+
type: Input
|
|
3517
|
+
}], responsiveStrategy: [{
|
|
3518
|
+
type: Input
|
|
3519
|
+
}], className: [{
|
|
3520
|
+
type: Input
|
|
3521
|
+
}], fullBleed: [{
|
|
3522
|
+
type: Input
|
|
3523
|
+
}], reorderRows: [{
|
|
3524
|
+
type: Input
|
|
3525
|
+
}], dragHandleSelector: [{
|
|
3526
|
+
type: Input
|
|
3527
|
+
}], rowOrderChange: [{
|
|
3528
|
+
type: Output
|
|
3529
|
+
}], tableElement: [{
|
|
3530
|
+
type: ViewChild,
|
|
3531
|
+
args: ['tableElement']
|
|
3532
|
+
}] } });
|
|
3533
|
+
|
|
2479
3534
|
class PdmDropdownMenuComponent {
|
|
2480
3535
|
constructor(elementRef, cdr, overlay, viewContainerRef) {
|
|
2481
3536
|
this.elementRef = elementRef;
|
|
@@ -2575,7 +3630,9 @@ class PdmDropdownMenuComponent {
|
|
|
2575
3630
|
}
|
|
2576
3631
|
}
|
|
2577
3632
|
onEsc() {
|
|
2578
|
-
this.
|
|
3633
|
+
if (this.open) {
|
|
3634
|
+
this.closePanel();
|
|
3635
|
+
}
|
|
2579
3636
|
}
|
|
2580
3637
|
openPanel() {
|
|
2581
3638
|
if (this.overlayRef)
|
|
@@ -2588,7 +3645,7 @@ class PdmDropdownMenuComponent {
|
|
|
2588
3645
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 8);
|
|
2589
3646
|
// Resolve panelClass: overlayOptions.panelClass wins; otherwise map panelClassName.
|
|
2590
3647
|
const resolvedPanelClass = this.overlayOptions?.panelClass
|
|
2591
|
-
?? (this.panelClassName ? [
|
|
3648
|
+
?? (this.panelClassName ? [Z_INDEX.popover, this.panelClassName] : [Z_INDEX.popover]);
|
|
2592
3649
|
this.overlayRef = this.overlay.create({
|
|
2593
3650
|
positionStrategy,
|
|
2594
3651
|
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
@@ -2659,13 +3716,67 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2659
3716
|
args: ['document:keydown.escape']
|
|
2660
3717
|
}] } });
|
|
2661
3718
|
|
|
3719
|
+
/**
|
|
3720
|
+
* Drawer/Sheet component con soporte responsive
|
|
3721
|
+
*
|
|
3722
|
+
* MEJORADO en v0.2.0:
|
|
3723
|
+
* - Posicionamiento configurable (bottom, left, right, top)
|
|
3724
|
+
* - Tamaños predefinidos
|
|
3725
|
+
* - Responsive: bottom sheet en mobile, side panel en desktop
|
|
3726
|
+
* - Contenido genérico via ng-content
|
|
3727
|
+
*
|
|
3728
|
+
* @example
|
|
3729
|
+
* // Drawer simple desde el bottom
|
|
3730
|
+
* <pdm-drawer [open]="isOpen" position="bottom">
|
|
3731
|
+
* <h3>Title</h3>
|
|
3732
|
+
* <p>Content</p>
|
|
3733
|
+
* </pdm-drawer>
|
|
3734
|
+
*
|
|
3735
|
+
* @example
|
|
3736
|
+
* // Side panel desde la right
|
|
3737
|
+
* <pdm-drawer [open]="isOpen" position="right" size="md">
|
|
3738
|
+
* <p>Content</p>
|
|
3739
|
+
* </pdm-drawer>
|
|
3740
|
+
*/
|
|
2662
3741
|
class PdmDrawerComponent {
|
|
2663
3742
|
constructor() {
|
|
2664
3743
|
this.open = false;
|
|
3744
|
+
/**
|
|
3745
|
+
* Posición del drawer
|
|
3746
|
+
* - bottom: desde abajo (default, mejor para mobile)
|
|
3747
|
+
* - left: side panel desde izquierda
|
|
3748
|
+
* - right: side panel desde derecha
|
|
3749
|
+
* - top: desde arriba (poco común)
|
|
3750
|
+
*/
|
|
3751
|
+
this.position = 'bottom';
|
|
3752
|
+
/**
|
|
3753
|
+
* Tamaño del drawer
|
|
3754
|
+
* - sm: 400px (side) / 50vh (bottom/top)
|
|
3755
|
+
* - md: 500px (side) / 66vh (bottom/top) (default)
|
|
3756
|
+
* - lg: 640px (side) / 80vh (bottom/top)
|
|
3757
|
+
* - full: 100% ancho/alto
|
|
3758
|
+
*/
|
|
3759
|
+
this.size = 'md';
|
|
3760
|
+
/**
|
|
3761
|
+
* @deprecated Use position="bottom" instead
|
|
3762
|
+
*/
|
|
2665
3763
|
this.variant = 'drawer';
|
|
2666
3764
|
this.className = '';
|
|
2667
3765
|
this.title = '';
|
|
2668
3766
|
this.description = '';
|
|
3767
|
+
/**
|
|
3768
|
+
* Mostrar handle visual (línea para arrastrar)
|
|
3769
|
+
* Solo tiene sentido en position="bottom"
|
|
3770
|
+
*/
|
|
3771
|
+
this.showHandle = true;
|
|
3772
|
+
/**
|
|
3773
|
+
* Mostrar botón de cerrar
|
|
3774
|
+
*/
|
|
3775
|
+
this.showCloseButton = true;
|
|
3776
|
+
this.closeOnEsc = true;
|
|
3777
|
+
this.closeOnBackdropClick = true;
|
|
3778
|
+
this.openChange = new EventEmitter();
|
|
3779
|
+
// DEPRECATED: contenido específico que se movió a ng-content
|
|
2669
3780
|
this.value = '';
|
|
2670
3781
|
this.unit = '';
|
|
2671
3782
|
this.decrementLabel = '-';
|
|
@@ -2679,10 +3790,19 @@ class PdmDrawerComponent {
|
|
|
2679
3790
|
this.usernameLabel = 'Username';
|
|
2680
3791
|
this.usernameValue = '';
|
|
2681
3792
|
this.responsivePrimaryLabel = '';
|
|
2682
|
-
this.
|
|
3793
|
+
this.bars = [];
|
|
2683
3794
|
this.primaryAction = new EventEmitter();
|
|
2684
3795
|
this.secondaryAction = new EventEmitter();
|
|
2685
|
-
|
|
3796
|
+
}
|
|
3797
|
+
onEsc() {
|
|
3798
|
+
if (this.open && this.closeOnEsc) {
|
|
3799
|
+
this.close();
|
|
3800
|
+
}
|
|
3801
|
+
}
|
|
3802
|
+
onBackdropClick() {
|
|
3803
|
+
if (this.closeOnBackdropClick) {
|
|
3804
|
+
this.close();
|
|
3805
|
+
}
|
|
2686
3806
|
}
|
|
2687
3807
|
close() {
|
|
2688
3808
|
this.openChange.emit(false);
|
|
@@ -2693,14 +3813,67 @@ class PdmDrawerComponent {
|
|
|
2693
3813
|
onSecondaryAction() {
|
|
2694
3814
|
this.secondaryAction.emit();
|
|
2695
3815
|
}
|
|
3816
|
+
get containerClassName() {
|
|
3817
|
+
return `fixed inset-0 ${Z_INDEX.drawer} ${this.className}`;
|
|
3818
|
+
}
|
|
3819
|
+
get panelClassName() {
|
|
3820
|
+
const base = [
|
|
3821
|
+
'absolute',
|
|
3822
|
+
'bg-background',
|
|
3823
|
+
'border',
|
|
3824
|
+
'border-border',
|
|
3825
|
+
'shadow-lg',
|
|
3826
|
+
'overflow-auto'
|
|
3827
|
+
];
|
|
3828
|
+
// Posicionamiento
|
|
3829
|
+
const positionClasses = this.getPositionClasses();
|
|
3830
|
+
// Tamaño
|
|
3831
|
+
const sizeClasses = this.getSizeClasses();
|
|
3832
|
+
return [...base, ...positionClasses, ...sizeClasses].filter(Boolean).join(' ');
|
|
3833
|
+
}
|
|
3834
|
+
getPositionClasses() {
|
|
3835
|
+
const map = {
|
|
3836
|
+
bottom: ['inset-x-0', 'bottom-0', 'rounded-t-xl'],
|
|
3837
|
+
top: ['inset-x-0', 'top-0', 'rounded-b-xl'],
|
|
3838
|
+
left: ['inset-y-0', 'left-0', 'rounded-r-xl'],
|
|
3839
|
+
right: ['inset-y-0', 'right-0', 'rounded-l-xl']
|
|
3840
|
+
};
|
|
3841
|
+
return map[this.position] || map.bottom;
|
|
3842
|
+
}
|
|
3843
|
+
getSizeClasses() {
|
|
3844
|
+
const isVertical = this.position === 'bottom' || this.position === 'top';
|
|
3845
|
+
if (this.size === 'full') {
|
|
3846
|
+
return ['w-full', 'h-full'];
|
|
3847
|
+
}
|
|
3848
|
+
const sizeMap = {
|
|
3849
|
+
sm: isVertical ? 'max-h-[50vh]' : 'max-w-[400px]',
|
|
3850
|
+
md: isVertical ? 'max-h-[66vh]' : 'max-w-[500px]',
|
|
3851
|
+
lg: isVertical ? 'max-h-[80vh]' : 'max-w-[640px]'
|
|
3852
|
+
};
|
|
3853
|
+
const maxDimension = sizeMap[this.size] || sizeMap.md;
|
|
3854
|
+
if (isVertical) {
|
|
3855
|
+
return ['w-full', maxDimension];
|
|
3856
|
+
}
|
|
3857
|
+
else {
|
|
3858
|
+
return ['h-full', maxDimension];
|
|
3859
|
+
}
|
|
3860
|
+
}
|
|
3861
|
+
get showLegacyContent() {
|
|
3862
|
+
// Mostrar contenido legacy si variant está siendo usado
|
|
3863
|
+
return this.variant === 'drawer' || this.variant === 'responsive-dialog';
|
|
3864
|
+
}
|
|
2696
3865
|
}
|
|
2697
3866
|
PdmDrawerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2698
|
-
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", bars: "bars" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, ngImport: i0, template: "<div *ngIf=\"open\"
|
|
3867
|
+
PdmDrawerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmDrawerComponent, selector: "pdm-drawer", inputs: { open: "open", position: "position", size: "size", variant: "variant", className: "className", title: "title", description: "description", showHandle: "showHandle", showCloseButton: "showCloseButton", closeOnEsc: "closeOnEsc", closeOnBackdropClick: "closeOnBackdropClick", value: "value", unit: "unit", decrementLabel: "decrementLabel", incrementLabel: "incrementLabel", primaryLabel: "primaryLabel", secondaryLabel: "secondaryLabel", profileTitle: "profileTitle", profileDescription: "profileDescription", nameLabel: "nameLabel", nameValue: "nameValue", usernameLabel: "usernameLabel", usernameValue: "usernameValue", responsivePrimaryLabel: "responsivePrimaryLabel", bars: "bars" }, outputs: { openChange: "openChange", primaryAction: "primaryAction", secondaryAction: "secondaryAction" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Panel -->\n <section [ngClass]=\"panelClassName\">\n <!-- Handle visual (solo para bottom) -->\n <div \n *ngIf=\"showHandle && position === 'bottom'\" \n class=\"mx-auto mb-4 mt-2 h-1 w-10 rounded-full bg-border\">\n </div>\n\n <!-- Header (opcional) -->\n <div *ngIf=\"title || description || showCloseButton\" class=\"flex items-start justify-between gap-4 p-6 pb-4\">\n <div *ngIf=\"title || description\" class=\"flex-1 min-w-0\">\n <h3 *ngIf=\"title\" class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">\n {{ title }}\n </h3>\n <p *ngIf=\"description\" class=\"m-0 mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </p>\n </div>\n \n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n (click)=\"close()\"\n aria-label=\"Close drawer\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"px-6 pb-6\">\n <!-- Contenido gen\u00E9rico -->\n <ng-container *ngIf=\"!showLegacyContent\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- LEGACY: contenido espec\u00EDfico hardcodeado (backward compatibility) -->\n <ng-container *ngIf=\"showLegacyContent\">\n <!-- Variant: drawer -->\n <div *ngIf=\"variant === 'drawer'\" class=\"mx-auto flex max-w-sm flex-col items-center\">\n <div *ngIf=\"value !== ''\" class=\"mt-3 flex w-full items-center justify-center gap-4\">\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ decrementLabel }}</button>\n <div class=\"text-center\">\n <div class=\"text-5xl font-semibold leading-none text-foreground\">{{ value }}</div>\n <div *ngIf=\"unit\" class=\"mt-1 text-xs tracking-wide text-muted-foreground\">{{ unit }}</div>\n </div>\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ incrementLabel }}</button>\n </div>\n\n <div *ngIf=\"bars.length\" class=\"mt-3 flex h-14 w-full items-end gap-1\">\n <div *ngFor=\"let bar of bars\" class=\"flex-1 bg-foreground\" [style.height.px]=\"bar\"></div>\n </div>\n\n <button *ngIf=\"primaryLabel\" type=\"button\" class=\"mt-3 h-9 w-full appearance-none rounded-md bg-primary text-sm font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ primaryLabel }}</button>\n <button *ngIf=\"secondaryLabel\" type=\"button\" class=\"mt-2 h-9 w-full appearance-none rounded-md border border-input bg-background text-sm font-medium text-foreground\" (click)=\"onSecondaryAction()\">{{ secondaryLabel }}</button>\n </div>\n\n <!-- Variant: responsive-dialog -->\n <div *ngIf=\"variant === 'responsive-dialog'\" class=\"flex flex-col gap-3\">\n <div *ngIf=\"nameLabel && nameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ nameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ nameValue }}</div>\n </div>\n <div *ngIf=\"usernameLabel && usernameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ usernameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ usernameValue }}</div>\n </div>\n\n <button *ngIf=\"responsivePrimaryLabel\" type=\"button\" class=\"mt-3 h-8 w-full appearance-none rounded-md bg-primary text-xs font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ responsivePrimaryLabel }}</button>\n </div>\n </ng-container>\n </div>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2699
3868
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmDrawerComponent, decorators: [{
|
|
2700
3869
|
type: Component,
|
|
2701
|
-
args: [{ selector: 'pdm-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\"
|
|
3870
|
+
args: [{ selector: 'pdm-drawer', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" [ngClass]=\"containerClassName\">\n <!-- Backdrop -->\n <div class=\"absolute inset-0 bg-foreground/30 backdrop-blur-sm\" (click)=\"onBackdropClick()\"></div>\n\n <!-- Panel -->\n <section [ngClass]=\"panelClassName\">\n <!-- Handle visual (solo para bottom) -->\n <div \n *ngIf=\"showHandle && position === 'bottom'\" \n class=\"mx-auto mb-4 mt-2 h-1 w-10 rounded-full bg-border\">\n </div>\n\n <!-- Header (opcional) -->\n <div *ngIf=\"title || description || showCloseButton\" class=\"flex items-start justify-between gap-4 p-6 pb-4\">\n <div *ngIf=\"title || description\" class=\"flex-1 min-w-0\">\n <h3 *ngIf=\"title\" class=\"m-0 text-lg font-semibold leading-none tracking-tight text-foreground\">\n {{ title }}\n </h3>\n <p *ngIf=\"description\" class=\"m-0 mt-1 text-sm text-muted-foreground\">\n {{ description }}\n </p>\n </div>\n \n <button\n *ngIf=\"showCloseButton\"\n type=\"button\"\n class=\"inline-flex h-6 w-6 flex-shrink-0 appearance-none items-center justify-center rounded-sm border-0 bg-transparent p-0 text-foreground opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2\"\n (click)=\"close()\"\n aria-label=\"Close drawer\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"h-4 w-4\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M6 6L18 18M18 6L6 18\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"></path>\n </svg>\n </button>\n </div>\n\n <!-- Content -->\n <div class=\"px-6 pb-6\">\n <!-- Contenido gen\u00E9rico -->\n <ng-container *ngIf=\"!showLegacyContent\">\n <ng-content></ng-content>\n </ng-container>\n\n <!-- LEGACY: contenido espec\u00EDfico hardcodeado (backward compatibility) -->\n <ng-container *ngIf=\"showLegacyContent\">\n <!-- Variant: drawer -->\n <div *ngIf=\"variant === 'drawer'\" class=\"mx-auto flex max-w-sm flex-col items-center\">\n <div *ngIf=\"value !== ''\" class=\"mt-3 flex w-full items-center justify-center gap-4\">\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ decrementLabel }}</button>\n <div class=\"text-center\">\n <div class=\"text-5xl font-semibold leading-none text-foreground\">{{ value }}</div>\n <div *ngIf=\"unit\" class=\"mt-1 text-xs tracking-wide text-muted-foreground\">{{ unit }}</div>\n </div>\n <button type=\"button\" class=\"inline-flex h-6 w-6 appearance-none items-center justify-center rounded-full border border-border bg-transparent p-0 text-muted-foreground\">{{ incrementLabel }}</button>\n </div>\n\n <div *ngIf=\"bars.length\" class=\"mt-3 flex h-14 w-full items-end gap-1\">\n <div *ngFor=\"let bar of bars\" class=\"flex-1 bg-foreground\" [style.height.px]=\"bar\"></div>\n </div>\n\n <button *ngIf=\"primaryLabel\" type=\"button\" class=\"mt-3 h-9 w-full appearance-none rounded-md bg-primary text-sm font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ primaryLabel }}</button>\n <button *ngIf=\"secondaryLabel\" type=\"button\" class=\"mt-2 h-9 w-full appearance-none rounded-md border border-input bg-background text-sm font-medium text-foreground\" (click)=\"onSecondaryAction()\">{{ secondaryLabel }}</button>\n </div>\n\n <!-- Variant: responsive-dialog -->\n <div *ngIf=\"variant === 'responsive-dialog'\" class=\"flex flex-col gap-3\">\n <div *ngIf=\"nameLabel && nameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ nameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ nameValue }}</div>\n </div>\n <div *ngIf=\"usernameLabel && usernameValue\">\n <label class=\"mb-1 block text-xs font-medium text-foreground\">{{ usernameLabel }}</label>\n <div class=\"h-8 rounded-md border border-border bg-background px-2 py-1 text-xs text-foreground\">{{ usernameValue }}</div>\n </div>\n\n <button *ngIf=\"responsivePrimaryLabel\" type=\"button\" class=\"mt-3 h-8 w-full appearance-none rounded-md bg-primary text-xs font-medium text-primary-foreground\" (click)=\"onPrimaryAction()\">{{ responsivePrimaryLabel }}</button>\n </div>\n </ng-container>\n </div>\n </section>\n</div>\n" }]
|
|
2702
3871
|
}], propDecorators: { open: [{
|
|
2703
3872
|
type: Input
|
|
3873
|
+
}], position: [{
|
|
3874
|
+
type: Input
|
|
3875
|
+
}], size: [{
|
|
3876
|
+
type: Input
|
|
2704
3877
|
}], variant: [{
|
|
2705
3878
|
type: Input
|
|
2706
3879
|
}], className: [{
|
|
@@ -2709,6 +3882,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2709
3882
|
type: Input
|
|
2710
3883
|
}], description: [{
|
|
2711
3884
|
type: Input
|
|
3885
|
+
}], showHandle: [{
|
|
3886
|
+
type: Input
|
|
3887
|
+
}], showCloseButton: [{
|
|
3888
|
+
type: Input
|
|
3889
|
+
}], closeOnEsc: [{
|
|
3890
|
+
type: Input
|
|
3891
|
+
}], closeOnBackdropClick: [{
|
|
3892
|
+
type: Input
|
|
3893
|
+
}], openChange: [{
|
|
3894
|
+
type: Output
|
|
2712
3895
|
}], value: [{
|
|
2713
3896
|
type: Input
|
|
2714
3897
|
}], unit: [{
|
|
@@ -2735,14 +3918,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
2735
3918
|
type: Input
|
|
2736
3919
|
}], responsivePrimaryLabel: [{
|
|
2737
3920
|
type: Input
|
|
2738
|
-
}],
|
|
2739
|
-
type:
|
|
3921
|
+
}], bars: [{
|
|
3922
|
+
type: Input
|
|
2740
3923
|
}], primaryAction: [{
|
|
2741
3924
|
type: Output
|
|
2742
3925
|
}], secondaryAction: [{
|
|
2743
3926
|
type: Output
|
|
2744
|
-
}],
|
|
2745
|
-
type:
|
|
3927
|
+
}], onEsc: [{
|
|
3928
|
+
type: HostListener,
|
|
3929
|
+
args: ['document:keydown.escape']
|
|
2746
3930
|
}] } });
|
|
2747
3931
|
|
|
2748
3932
|
class PdmEmptyComponent {
|
|
@@ -2884,10 +4068,10 @@ class PdmHoverCardComponent {
|
|
|
2884
4068
|
}
|
|
2885
4069
|
}
|
|
2886
4070
|
PdmHoverCardComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2887
|
-
PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-
|
|
4071
|
+
PdmHoverCardComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmHoverCardComponent, selector: "pdm-hover-card", inputs: { className: "className", panelClassName: "panelClassName", side: "side", align: "align", panelWidth: "panelWidth" }, ngImport: i0, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
2888
4072
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmHoverCardComponent, decorators: [{
|
|
2889
4073
|
type: Component,
|
|
2890
|
-
args: [{ selector: 'pdm-hover-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-
|
|
4074
|
+
args: [{ selector: 'pdm-hover-card', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n class=\"relative inline-flex\"\n [ngClass]=\"className\"\n (mouseenter)=\"open = true\"\n (mouseleave)=\"open = false\"\n (focusin)=\"open = true\"\n (focusout)=\"open = false\"\n>\n <div>\n <ng-content select=\"[pdmHoverTrigger]\"></ng-content>\n </div>\n\n <section\n *ngIf=\"open\"\n [style.width.px]=\"panelWidth\"\n [ngClass]=\"[\n 'absolute z-[70] rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md',\n positionClass,\n panelClassName\n ]\"\n >\n <ng-content select=\"[pdmHoverContent]\"></ng-content>\n </section>\n</div>\n" }]
|
|
2891
4075
|
}], propDecorators: { className: [{
|
|
2892
4076
|
type: Input
|
|
2893
4077
|
}], panelClassName: [{
|
|
@@ -3274,12 +4458,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3274
4458
|
}] } });
|
|
3275
4459
|
|
|
3276
4460
|
class PdmMenubarComponent {
|
|
3277
|
-
constructor() {
|
|
4461
|
+
constructor(elementRef, cdr) {
|
|
4462
|
+
this.elementRef = elementRef;
|
|
4463
|
+
this.cdr = cdr;
|
|
3278
4464
|
this.menus = [];
|
|
3279
4465
|
this.className = '';
|
|
3280
4466
|
this.itemSelect = new EventEmitter();
|
|
3281
4467
|
this.openIndex = -1;
|
|
3282
4468
|
}
|
|
4469
|
+
ngOnInit() {
|
|
4470
|
+
this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
|
|
4471
|
+
document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
4472
|
+
}
|
|
4473
|
+
ngOnDestroy() {
|
|
4474
|
+
if (this.boundPointerDown) {
|
|
4475
|
+
document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
onEsc() {
|
|
4479
|
+
if (this.openIndex >= 0) {
|
|
4480
|
+
this.openIndex = -1;
|
|
4481
|
+
this.cdr.markForCheck();
|
|
4482
|
+
}
|
|
4483
|
+
}
|
|
3283
4484
|
toggle(index) {
|
|
3284
4485
|
this.openIndex = this.openIndex === index ? -1 : index;
|
|
3285
4486
|
}
|
|
@@ -3293,18 +4494,32 @@ class PdmMenubarComponent {
|
|
|
3293
4494
|
}
|
|
3294
4495
|
this.select(item.value);
|
|
3295
4496
|
}
|
|
4497
|
+
onDocumentPointerDown(event) {
|
|
4498
|
+
if (this.openIndex < 0)
|
|
4499
|
+
return;
|
|
4500
|
+
const target = event.target;
|
|
4501
|
+
if (!target)
|
|
4502
|
+
return;
|
|
4503
|
+
if (!this.elementRef.nativeElement.contains(target)) {
|
|
4504
|
+
this.openIndex = -1;
|
|
4505
|
+
this.cdr.markForCheck();
|
|
4506
|
+
}
|
|
4507
|
+
}
|
|
3296
4508
|
}
|
|
3297
|
-
PdmMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3298
|
-
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" }, 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-
|
|
4509
|
+
PdmMenubarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4510
|
+
PdmMenubarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmMenubarComponent, selector: "pdm-menubar", inputs: { menus: "menus", className: "className" }, outputs: { itemSelect: "itemSelect" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3299
4511
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmMenubarComponent, decorators: [{
|
|
3300
4512
|
type: Component,
|
|
3301
|
-
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-
|
|
3302
|
-
}], propDecorators: { menus: [{
|
|
4513
|
+
args: [{ selector: 'pdm-menubar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav role=\"menubar\" [ngClass]=\"['inline-flex h-9 items-center gap-0.5 rounded-md border border-border bg-background p-1 shadow-sm', className]\">\n <div *ngFor=\"let menu of menus; let i = index\" class=\"relative\">\n <button type=\"button\" class=\"inline-flex h-7 appearance-none items-center rounded-sm border-0 bg-transparent px-3 text-sm text-foreground hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background\" (click)=\"toggle(i)\">{{ menu.label }}</button>\n <div *ngIf=\"openIndex === i\" class=\"absolute left-0 top-full z-[70] mt-1 min-w-40 rounded-md border border-border bg-popover p-1 text-popover-foreground shadow-md sm:min-w-48\">\n <button\n *ngFor=\"let item of menu.items\"\n type=\"button\"\n [disabled]=\"item.disabled || !item.value\"\n class=\"relative flex w-full appearance-none cursor-default select-none items-center rounded-sm border-0 bg-transparent px-2 py-1.5 text-sm outline-none transition-colors hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground disabled:pointer-events-none disabled:opacity-50\"\n (click)=\"selectItem(item)\"\n >\n {{ item.label }}\n </button>\n </div>\n </div>\n</nav>\n" }]
|
|
4514
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { menus: [{
|
|
3303
4515
|
type: Input
|
|
3304
4516
|
}], className: [{
|
|
3305
4517
|
type: Input
|
|
3306
4518
|
}], itemSelect: [{
|
|
3307
4519
|
type: Output
|
|
4520
|
+
}], onEsc: [{
|
|
4521
|
+
type: HostListener,
|
|
4522
|
+
args: ['document:keydown.escape']
|
|
3308
4523
|
}] } });
|
|
3309
4524
|
|
|
3310
4525
|
class PdmNativeSelectComponent {
|
|
@@ -3345,21 +4560,125 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3345
4560
|
type: Output
|
|
3346
4561
|
}] } });
|
|
3347
4562
|
|
|
4563
|
+
/**
|
|
4564
|
+
* Navigation Menu component - Navegación horizontal responsive
|
|
4565
|
+
*
|
|
4566
|
+
* MEJORAS en v0.2.0:
|
|
4567
|
+
* - Modo scroll: overflow-x-auto con scroll indicators en mobile
|
|
4568
|
+
* - Modo compact: items abreviados en mobile, completos en desktop
|
|
4569
|
+
* - Scroll smooth automático al item activo
|
|
4570
|
+
*
|
|
4571
|
+
* @example
|
|
4572
|
+
* <!-- Scroll horizontal (default) -->
|
|
4573
|
+
* <pdm-navigation-menu [items]="navItems"></pdm-navigation-menu>
|
|
4574
|
+
*
|
|
4575
|
+
* <!-- Compact mode -->
|
|
4576
|
+
* <pdm-navigation-menu [items]="navItems" mobileMode="compact"></pdm-navigation-menu>
|
|
4577
|
+
*/
|
|
3348
4578
|
class PdmNavigationMenuComponent {
|
|
3349
4579
|
constructor() {
|
|
3350
4580
|
this.items = [];
|
|
3351
4581
|
this.className = '';
|
|
4582
|
+
/**
|
|
4583
|
+
* Mobile behavior: 'scroll' (horizontal scroll) o 'compact' (items reducidos)
|
|
4584
|
+
* @default 'scroll'
|
|
4585
|
+
*/
|
|
4586
|
+
this.mobileMode = 'scroll';
|
|
3352
4587
|
}
|
|
3353
4588
|
}
|
|
3354
4589
|
PdmNavigationMenuComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3355
|
-
PdmNavigationMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmNavigationMenuComponent, selector: "pdm-navigation-menu", inputs: { items: "items", className: "className" }, ngImport: i0, template: "<nav
|
|
4590
|
+
PdmNavigationMenuComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmNavigationMenuComponent, selector: "pdm-navigation-menu", inputs: { items: "items", className: "className", mobileMode: "mobileMode" }, ngImport: i0, template: "<nav\n [ngClass]=\"[\n 'relative z-10 flex w-full items-center',\n mobileMode === 'scroll' ? 'overflow-x-auto scrollbar-thin' : '',\n className\n ]\"\n>\n <ul\n [ngClass]=\"[\n 'group flex list-none items-center gap-1',\n mobileMode === 'scroll' ? 'flex-nowrap' : 'flex-wrap justify-center'\n ]\"\n >\n <li *ngFor=\"let item of items\">\n <a\n [href]=\"item.href || '#'\"\n [ngClass]=\"[\n 'group inline-flex h-9 items-center justify-center rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 whitespace-nowrap',\n item.active ? 'bg-accent text-accent-foreground' : 'text-foreground'\n ]\"\n >\n {{ item.label }}\n </a>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3356
4591
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmNavigationMenuComponent, decorators: [{
|
|
3357
4592
|
type: Component,
|
|
3358
|
-
args: [{ selector: 'pdm-navigation-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav
|
|
4593
|
+
args: [{ selector: 'pdm-navigation-menu', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n [ngClass]=\"[\n 'relative z-10 flex w-full items-center',\n mobileMode === 'scroll' ? 'overflow-x-auto scrollbar-thin' : '',\n className\n ]\"\n>\n <ul\n [ngClass]=\"[\n 'group flex list-none items-center gap-1',\n mobileMode === 'scroll' ? 'flex-nowrap' : 'flex-wrap justify-center'\n ]\"\n >\n <li *ngFor=\"let item of items\">\n <a\n [href]=\"item.href || '#'\"\n [ngClass]=\"[\n 'group inline-flex h-9 items-center justify-center rounded-md px-3 py-2 text-sm font-medium transition-colors hover:bg-accent hover:text-accent-foreground ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 whitespace-nowrap',\n item.active ? 'bg-accent text-accent-foreground' : 'text-foreground'\n ]\"\n >\n {{ item.label }}\n </a>\n </li>\n </ul>\n</nav>\n" }]
|
|
3359
4594
|
}], propDecorators: { items: [{
|
|
3360
4595
|
type: Input
|
|
3361
4596
|
}], className: [{
|
|
3362
4597
|
type: Input
|
|
4598
|
+
}], mobileMode: [{
|
|
4599
|
+
type: Input
|
|
4600
|
+
}] } });
|
|
4601
|
+
|
|
4602
|
+
/**
|
|
4603
|
+
* Emits `(pdmOutsideClick)` whenever a `pointerdown` event fires outside the host element.
|
|
4604
|
+
*
|
|
4605
|
+
* Uses the CAPTURE phase so it intercepts clicks even when inner elements call
|
|
4606
|
+
* `stopPropagation()` (e.g. CDK overlay panels).
|
|
4607
|
+
*
|
|
4608
|
+
* SSR-safe: no listener is registered when running on the server.
|
|
4609
|
+
*
|
|
4610
|
+
* @example
|
|
4611
|
+
* ```html
|
|
4612
|
+
* <div [pdmOutsideClick]
|
|
4613
|
+
* (pdmOutsideClick)="close()"
|
|
4614
|
+
* [pdmOutsideClickDisabled]="!open">
|
|
4615
|
+
* </div>
|
|
4616
|
+
* ```
|
|
4617
|
+
*/
|
|
4618
|
+
class PdmOutsideClickDirective {
|
|
4619
|
+
constructor(elementRef, document, platformId) {
|
|
4620
|
+
this.elementRef = elementRef;
|
|
4621
|
+
this.document = document;
|
|
4622
|
+
/** When `true`, the outside-click listener is inactive. */
|
|
4623
|
+
this.pdmOutsideClickDisabled = false;
|
|
4624
|
+
/**
|
|
4625
|
+
* Additional elements to exclude from the "outside" check.
|
|
4626
|
+
* Useful when the trigger lives outside the host (e.g. a menubar button
|
|
4627
|
+
* that opens a floating panel bound to a different root element).
|
|
4628
|
+
*/
|
|
4629
|
+
this.pdmOutsideClickExclude = [];
|
|
4630
|
+
/** Fires when a `pointerdown` lands outside the host (and excluded elements). */
|
|
4631
|
+
this.pdmOutsideClick = new EventEmitter();
|
|
4632
|
+
this.isBrowser = isPlatformBrowser(platformId);
|
|
4633
|
+
}
|
|
4634
|
+
ngOnInit() {
|
|
4635
|
+
if (!this.isBrowser)
|
|
4636
|
+
return;
|
|
4637
|
+
this.boundHandler = (event) => this.onPointerDown(event);
|
|
4638
|
+
this.document.addEventListener('pointerdown', this.boundHandler, { capture: true });
|
|
4639
|
+
}
|
|
4640
|
+
ngOnDestroy() {
|
|
4641
|
+
if (!this.isBrowser || !this.boundHandler)
|
|
4642
|
+
return;
|
|
4643
|
+
this.document.removeEventListener('pointerdown', this.boundHandler, { capture: true });
|
|
4644
|
+
}
|
|
4645
|
+
onPointerDown(event) {
|
|
4646
|
+
if (this.pdmOutsideClickDisabled)
|
|
4647
|
+
return;
|
|
4648
|
+
const target = event.target;
|
|
4649
|
+
if (!target)
|
|
4650
|
+
return;
|
|
4651
|
+
// Check if click is inside the host element.
|
|
4652
|
+
if (this.elementRef.nativeElement.contains(target))
|
|
4653
|
+
return;
|
|
4654
|
+
// Check if click is inside any excluded element.
|
|
4655
|
+
for (const excluded of this.pdmOutsideClickExclude) {
|
|
4656
|
+
const el = excluded instanceof ElementRef ? excluded.nativeElement : excluded;
|
|
4657
|
+
if (el && el.contains(target))
|
|
4658
|
+
return;
|
|
4659
|
+
}
|
|
4660
|
+
this.pdmOutsideClick.emit(event);
|
|
4661
|
+
}
|
|
4662
|
+
}
|
|
4663
|
+
PdmOutsideClickDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmOutsideClickDirective, deps: [{ token: i0.ElementRef }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Directive });
|
|
4664
|
+
PdmOutsideClickDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.3.0", type: PdmOutsideClickDirective, selector: "[pdmOutsideClick]", inputs: { pdmOutsideClickDisabled: "pdmOutsideClickDisabled", pdmOutsideClickExclude: "pdmOutsideClickExclude" }, outputs: { pdmOutsideClick: "pdmOutsideClick" }, ngImport: i0 });
|
|
4665
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmOutsideClickDirective, decorators: [{
|
|
4666
|
+
type: Directive,
|
|
4667
|
+
args: [{
|
|
4668
|
+
selector: '[pdmOutsideClick]'
|
|
4669
|
+
}]
|
|
4670
|
+
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: Document, decorators: [{
|
|
4671
|
+
type: Inject,
|
|
4672
|
+
args: [DOCUMENT]
|
|
4673
|
+
}] }, { type: undefined, decorators: [{
|
|
4674
|
+
type: Inject,
|
|
4675
|
+
args: [PLATFORM_ID]
|
|
4676
|
+
}] }]; }, propDecorators: { pdmOutsideClickDisabled: [{
|
|
4677
|
+
type: Input
|
|
4678
|
+
}], pdmOutsideClickExclude: [{
|
|
4679
|
+
type: Input
|
|
4680
|
+
}], pdmOutsideClick: [{
|
|
4681
|
+
type: Output
|
|
3363
4682
|
}] } });
|
|
3364
4683
|
|
|
3365
4684
|
/**
|
|
@@ -3481,7 +4800,9 @@ class PdmSelectComponent {
|
|
|
3481
4800
|
this.closePanel();
|
|
3482
4801
|
}
|
|
3483
4802
|
onEscape() {
|
|
3484
|
-
this.
|
|
4803
|
+
if (this.open) {
|
|
4804
|
+
this.closePanel();
|
|
4805
|
+
}
|
|
3485
4806
|
}
|
|
3486
4807
|
openPanel() {
|
|
3487
4808
|
if (this.overlayRef)
|
|
@@ -3493,8 +4814,9 @@ class PdmSelectComponent {
|
|
|
3493
4814
|
this.cdr.markForCheck();
|
|
3494
4815
|
const positionStrategy = createFlexiblePositionStrategy(this.overlay, triggerEl, 4);
|
|
3495
4816
|
this.overlayRef = this.overlay.create({
|
|
3496
|
-
//
|
|
3497
|
-
panelClass
|
|
4817
|
+
// CRÍTICO: z-[70] para aparecer SOBRE modals (z-[60])
|
|
4818
|
+
// panelClass se aplica al cdk-overlay-pane wrapper
|
|
4819
|
+
panelClass: [Z_INDEX.popover],
|
|
3498
4820
|
positionStrategy,
|
|
3499
4821
|
scrollStrategy: this.overlay.scrollStrategies.reposition(),
|
|
3500
4822
|
width: triggerEl.offsetWidth,
|
|
@@ -3609,10 +4931,10 @@ class PdmPaginationComponent {
|
|
|
3609
4931
|
}
|
|
3610
4932
|
}
|
|
3611
4933
|
PdmPaginationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3612
|
-
PdmPaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPaginationComponent, selector: "pdm-pagination", inputs: { page: "page", pageCount: "pageCount", maxVisible: "maxVisible", className: "className", rowsPerPageLabel: "rowsPerPageLabel", rowsPerPage: "rowsPerPage", rowsPerPageOptions: "rowsPerPageOptions" }, outputs: { pageChange: "pageChange", rowsPerPageChange: "rowsPerPageChange" }, ngImport: i0, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }, { kind: "component", type: PdmSelectComponent, selector: "pdm-select", inputs: ["id", "value", "options", "disabled", "invalid", "className", "placeholder", "overlayOptions"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4934
|
+
PdmPaginationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPaginationComponent, selector: "pdm-pagination", inputs: { page: "page", pageCount: "pageCount", maxVisible: "maxVisible", className: "className", rowsPerPageLabel: "rowsPerPageLabel", rowsPerPage: "rowsPerPage", rowsPerPageOptions: "rowsPerPageOptions" }, outputs: { pageChange: "pageChange", rowsPerPageChange: "rowsPerPageChange" }, ngImport: i0, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[100px] sm:w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }, { kind: "component", type: PdmSelectComponent, selector: "pdm-select", inputs: ["id", "value", "options", "disabled", "invalid", "className", "placeholder", "overlayOptions"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3613
4935
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPaginationComponent, decorators: [{
|
|
3614
4936
|
type: Component,
|
|
3615
|
-
args: [{ selector: 'pdm-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n" }]
|
|
4937
|
+
args: [{ selector: 'pdm-pagination', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"Pagination\"\n [ngClass]=\"[\n 'mx-auto flex w-full flex-wrap items-center justify-center gap-4',\n className,\n ]\"\n>\n <div class=\"flex items-center gap-3\" *ngIf=\"rowsPerPageOptions.length > 0\">\n <span class=\"text-sm font-medium text-foreground\">{{\n rowsPerPageLabel\n }}</span>\n <pdm-select\n [value]=\"rowsPerPageValue\"\n [options]=\"rowsPerPageSelectOptions\"\n [placeholder]=\"rowsPerPageValue\"\n className=\"w-[100px] sm:w-[120px]\"\n (valueChange)=\"onRowsPerPageChangeValue($event)\"\n ></pdm-select>\n </div>\n\n <ul class=\"m-0 flex list-none items-center gap-1 p-0\">\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page <= 1\"\n (click)=\"setPage(page - 1)\"\n >\n <pdm-icon name=\"chevron-left\" [size]=\"14\"></pdm-icon>\n Previous\n </button>\n </li>\n <li *ngFor=\"let pageNumber of visiblePages\">\n <ng-container *ngIf=\"pageNumber === 'ellipsis'; else pageButton\">\n <span\n class=\"inline-flex h-9 min-w-9 items-center justify-center px-2 text-sm text-muted-foreground\"\n >...</span\n >\n </ng-container>\n <ng-template #pageButton>\n <button\n type=\"button\"\n [ngClass]=\"[\n 'inline-flex h-9 min-w-9 items-center justify-center rounded-md px-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n pageNumber === page\n ? 'appearance-none border border-border bg-muted text-foreground shadow-sm'\n : 'appearance-none border-0 bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground',\n ]\"\n (click)=\"setPage(+pageNumber)\"\n >\n {{ pageNumber }}\n </button>\n </ng-template>\n </li>\n <li>\n <button\n type=\"button\"\n class=\"inline-flex h-9 appearance-none items-center justify-center gap-1 rounded-md border-0 bg-transparent px-2 text-sm text-foreground hover:bg-accent disabled:opacity-50 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n [disabled]=\"page >= pageCount\"\n (click)=\"setPage(page + 1)\"\n >\n Next\n <pdm-icon name=\"chevron-right\" [size]=\"14\"></pdm-icon>\n </button>\n </li>\n </ul>\n</nav>\n" }]
|
|
3616
4938
|
}], propDecorators: { page: [{
|
|
3617
4939
|
type: Input
|
|
3618
4940
|
}], pageCount: [{
|
|
@@ -3645,6 +4967,15 @@ class PdmPopoverComponent {
|
|
|
3645
4967
|
this.openChange = new EventEmitter();
|
|
3646
4968
|
this.panelPlacement = 'bottom';
|
|
3647
4969
|
}
|
|
4970
|
+
ngOnInit() {
|
|
4971
|
+
this.boundPointerDown = (event) => this.onDocumentPointerDown(event);
|
|
4972
|
+
document.addEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
4973
|
+
}
|
|
4974
|
+
ngOnDestroy() {
|
|
4975
|
+
if (this.boundPointerDown) {
|
|
4976
|
+
document.removeEventListener('pointerdown', this.boundPointerDown, { capture: true });
|
|
4977
|
+
}
|
|
4978
|
+
}
|
|
3648
4979
|
set open(value) {
|
|
3649
4980
|
this._open = !!value;
|
|
3650
4981
|
if (this._open) {
|
|
@@ -3659,10 +4990,11 @@ class PdmPopoverComponent {
|
|
|
3659
4990
|
return this._open;
|
|
3660
4991
|
}
|
|
3661
4992
|
get panelClasses() {
|
|
4993
|
+
const baseClasses = 'min-w-80 rounded-md border border-border bg-popover p-4 text-popover-foreground shadow-md';
|
|
3662
4994
|
return [
|
|
3663
4995
|
this.panelPlacement === 'top'
|
|
3664
|
-
?
|
|
3665
|
-
:
|
|
4996
|
+
? `absolute bottom-full left-0 ${Z_INDEX.popover} mb-2 ${baseClasses}`
|
|
4997
|
+
: `absolute left-0 top-full ${Z_INDEX.popover} mt-2 ${baseClasses}`,
|
|
3666
4998
|
this.panelClassName
|
|
3667
4999
|
];
|
|
3668
5000
|
}
|
|
@@ -3676,7 +5008,10 @@ class PdmPopoverComponent {
|
|
|
3676
5008
|
this.openChange.emit(false);
|
|
3677
5009
|
}
|
|
3678
5010
|
}
|
|
3679
|
-
|
|
5011
|
+
onViewportChange() {
|
|
5012
|
+
this.updatePanelPlacement();
|
|
5013
|
+
}
|
|
5014
|
+
onDocumentPointerDown(event) {
|
|
3680
5015
|
if (!this.open)
|
|
3681
5016
|
return;
|
|
3682
5017
|
const target = event.target;
|
|
@@ -3685,9 +5020,6 @@ class PdmPopoverComponent {
|
|
|
3685
5020
|
this.openChange.emit(false);
|
|
3686
5021
|
}
|
|
3687
5022
|
}
|
|
3688
|
-
onViewportChange() {
|
|
3689
|
-
this.updatePanelPlacement();
|
|
3690
|
-
}
|
|
3691
5023
|
schedulePanelPlacementUpdate() {
|
|
3692
5024
|
setTimeout(() => this.updatePanelPlacement());
|
|
3693
5025
|
}
|
|
@@ -3713,7 +5045,7 @@ class PdmPopoverComponent {
|
|
|
3713
5045
|
}
|
|
3714
5046
|
}
|
|
3715
5047
|
PdmPopoverComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
3716
|
-
PdmPopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPopoverComponent, selector: "pdm-popover", inputs: { triggerText: "triggerText", className: "className", panelClassName: "panelClassName", showTrigger: "showTrigger", open: "open" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()", "
|
|
5048
|
+
PdmPopoverComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmPopoverComponent, selector: "pdm-popover", inputs: { triggerText: "triggerText", className: "className", panelClassName: "panelClassName", showTrigger: "showTrigger", open: "open" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()", "window:resize": "onViewportChange()", "window:scroll": "onViewportChange()" } }, viewQueries: [{ propertyName: "anchorRef", first: true, predicate: ["anchorEl"], descendants: true }, { propertyName: "triggerRef", first: true, predicate: ["triggerEl"], descendants: true }, { propertyName: "panelRef", first: true, predicate: ["panelEl"], descendants: true }], ngImport: i0, template: "<div #anchorEl class=\"relative inline-block\" [ngClass]=\"className\">\n <button #triggerEl *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div #panelEl *ngIf=\"open || !showTrigger\" [ngClass]=\"panelClasses\">\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.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3717
5049
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmPopoverComponent, decorators: [{
|
|
3718
5050
|
type: Component,
|
|
3719
5051
|
args: [{ selector: 'pdm-popover', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div #anchorEl class=\"relative inline-block\" [ngClass]=\"className\">\n <button #triggerEl *ngIf=\"showTrigger\" type=\"button\" class=\"inline-flex h-9 appearance-none items-center justify-center rounded-md border border-input bg-background px-3 text-sm font-medium text-foreground shadow-sm\" [attr.aria-expanded]=\"open\" (click)=\"toggle()\">{{ triggerText }}</button>\n <div #panelEl *ngIf=\"open || !showTrigger\" [ngClass]=\"panelClasses\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
|
|
@@ -3741,9 +5073,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3741
5073
|
}], onEsc: [{
|
|
3742
5074
|
type: HostListener,
|
|
3743
5075
|
args: ['document:keydown.escape']
|
|
3744
|
-
}], onDocumentClick: [{
|
|
3745
|
-
type: HostListener,
|
|
3746
|
-
args: ['document:click', ['$event']]
|
|
3747
5076
|
}], onViewportChange: [{
|
|
3748
5077
|
type: HostListener,
|
|
3749
5078
|
args: ['window:resize']
|
|
@@ -3857,56 +5186,180 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
3857
5186
|
type: Input
|
|
3858
5187
|
}] } });
|
|
3859
5188
|
|
|
5189
|
+
/**
|
|
5190
|
+
* Sheet/Side panel component con soporte responsive
|
|
5191
|
+
*
|
|
5192
|
+
* MEJORADO en v0.2.0:
|
|
5193
|
+
* - Tamaños configurables
|
|
5194
|
+
* - Mejor manejo de overflow
|
|
5195
|
+
* - Responsive sizes
|
|
5196
|
+
*
|
|
5197
|
+
* @example
|
|
5198
|
+
* <pdm-sheet [open]="isOpen" side="right" size="md">
|
|
5199
|
+
* <h3>Settings</h3>
|
|
5200
|
+
* <p>Content here</p>
|
|
5201
|
+
* </pdm-sheet>
|
|
5202
|
+
*/
|
|
3860
5203
|
class PdmSheetComponent {
|
|
3861
5204
|
constructor() {
|
|
3862
5205
|
this.open = false;
|
|
5206
|
+
/**
|
|
5207
|
+
* Lado desde donde aparece el sheet
|
|
5208
|
+
*/
|
|
3863
5209
|
this.side = 'right';
|
|
5210
|
+
/**
|
|
5211
|
+
* Tamaño del sheet
|
|
5212
|
+
* - sm: 320px (side) / 40vh (top/bottom)
|
|
5213
|
+
* - md: 400px (side) / 50vh (top/bottom) (default)
|
|
5214
|
+
* - lg: 500px (side) / 66vh (top/bottom)
|
|
5215
|
+
* - xl: 640px (side) / 80vh (top/bottom)
|
|
5216
|
+
* - full: 100%
|
|
5217
|
+
*/
|
|
5218
|
+
this.size = 'md';
|
|
3864
5219
|
this.className = '';
|
|
5220
|
+
this.closeOnEsc = true;
|
|
5221
|
+
this.closeOnBackdropClick = true;
|
|
3865
5222
|
this.openChange = new EventEmitter();
|
|
3866
5223
|
}
|
|
5224
|
+
onEsc() {
|
|
5225
|
+
if (this.open && this.closeOnEsc) {
|
|
5226
|
+
this.close();
|
|
5227
|
+
}
|
|
5228
|
+
}
|
|
5229
|
+
onBackdropClick() {
|
|
5230
|
+
if (this.closeOnBackdropClick) {
|
|
5231
|
+
this.close();
|
|
5232
|
+
}
|
|
5233
|
+
}
|
|
3867
5234
|
close() {
|
|
3868
5235
|
this.openChange.emit(false);
|
|
3869
5236
|
}
|
|
3870
5237
|
get panelClass() {
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
|
|
3877
|
-
|
|
5238
|
+
const base = 'absolute bg-background border-border shadow-lg overflow-auto';
|
|
5239
|
+
const position = this.getPositionClass();
|
|
5240
|
+
const sizing = this.getSizingClass();
|
|
5241
|
+
return `${base} ${position} ${sizing} ${this.className}`.trim();
|
|
5242
|
+
}
|
|
5243
|
+
getPositionClass() {
|
|
5244
|
+
const map = {
|
|
5245
|
+
left: 'left-0 top-0 h-full border-r',
|
|
5246
|
+
right: 'right-0 top-0 h-full border-l',
|
|
5247
|
+
top: 'top-0 left-0 w-full border-b',
|
|
5248
|
+
bottom: 'bottom-0 left-0 w-full border-t'
|
|
5249
|
+
};
|
|
5250
|
+
return map[this.side];
|
|
5251
|
+
}
|
|
5252
|
+
getSizingClass() {
|
|
5253
|
+
if (this.size === 'full') {
|
|
5254
|
+
return 'w-full h-full';
|
|
5255
|
+
}
|
|
5256
|
+
const isHorizontal = this.side === 'left' || this.side === 'right';
|
|
5257
|
+
if (isHorizontal) {
|
|
5258
|
+
const widthMap = {
|
|
5259
|
+
sm: 'w-full max-w-[320px] sm:max-w-[320px]',
|
|
5260
|
+
md: 'w-full max-w-[360px] sm:max-w-[400px]',
|
|
5261
|
+
lg: 'w-full max-w-[400px] sm:max-w-[500px]',
|
|
5262
|
+
xl: 'w-full max-w-[500px] sm:max-w-[640px]'
|
|
5263
|
+
};
|
|
5264
|
+
return widthMap[this.size] || widthMap.md;
|
|
5265
|
+
}
|
|
5266
|
+
else {
|
|
5267
|
+
const heightMap = {
|
|
5268
|
+
sm: 'max-h-[40vh]',
|
|
5269
|
+
md: 'max-h-[50vh]',
|
|
5270
|
+
lg: 'max-h-[66vh]',
|
|
5271
|
+
xl: 'max-h-[80vh]'
|
|
5272
|
+
};
|
|
5273
|
+
return heightMap[this.size] || heightMap.md;
|
|
5274
|
+
}
|
|
3878
5275
|
}
|
|
3879
5276
|
}
|
|
3880
5277
|
PdmSheetComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3881
|
-
PdmSheetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSheetComponent, selector: "pdm-sheet", inputs: { open: "open", side: "side", className: "className" }, outputs: { openChange: "openChange" }, 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)=\"
|
|
5278
|
+
PdmSheetComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSheetComponent, selector: "pdm-sheet", inputs: { open: "open", side: "side", size: "size", className: "className", closeOnEsc: "closeOnEsc", closeOnBackdropClick: "closeOnBackdropClick" }, outputs: { openChange: "openChange" }, host: { listeners: { "document:keydown.escape": "onEsc()" } }, ngImport: i0, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute z-[60] border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: PdmIconComponent, selector: "pdm-icon", inputs: ["name", "library", "assetUrl", "size", "strokeWidth", "className", "ariaLabel", "decorative"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3882
5279
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSheetComponent, decorators: [{
|
|
3883
5280
|
type: Component,
|
|
3884
|
-
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)=\"
|
|
5281
|
+
args: [{ selector: 'pdm-sheet', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div *ngIf=\"open\" class=\"fixed inset-0 z-50\">\n <button type=\"button\" class=\"absolute inset-0 appearance-none border-0 bg-foreground/80 p-0\" aria-label=\"Close sheet\" (click)=\"onBackdropClick()\"></button>\n\n <section [ngClass]=\"['absolute z-[60] border border-border bg-background p-6 shadow-lg', panelClass, className]\" role=\"dialog\" aria-modal=\"true\">\n <button type=\"button\" class=\"absolute right-3 top-3 appearance-none rounded-sm border-0 bg-transparent p-0 opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\" (click)=\"close()\">\n <pdm-icon name=\"x\" [size]=\"16\"></pdm-icon>\n </button>\n <ng-content></ng-content>\n </section>\n</div>\n" }]
|
|
3885
5282
|
}], propDecorators: { open: [{
|
|
3886
5283
|
type: Input
|
|
3887
5284
|
}], side: [{
|
|
3888
5285
|
type: Input
|
|
5286
|
+
}], size: [{
|
|
5287
|
+
type: Input
|
|
3889
5288
|
}], className: [{
|
|
3890
5289
|
type: Input
|
|
5290
|
+
}], closeOnEsc: [{
|
|
5291
|
+
type: Input
|
|
5292
|
+
}], closeOnBackdropClick: [{
|
|
5293
|
+
type: Input
|
|
3891
5294
|
}], openChange: [{
|
|
3892
5295
|
type: Output
|
|
5296
|
+
}], onEsc: [{
|
|
5297
|
+
type: HostListener,
|
|
5298
|
+
args: ['document:keydown.escape']
|
|
3893
5299
|
}] } });
|
|
3894
5300
|
|
|
5301
|
+
/**
|
|
5302
|
+
* Sidebar component - Navegación lateral responsive
|
|
5303
|
+
*
|
|
5304
|
+
* MEJORAS en v0.2.0:
|
|
5305
|
+
* - Mobile drawer mode: overlay fullscreen en mobile, sidebar fijo en desktop
|
|
5306
|
+
* - Sidebar mode: sidebar persistente con widths responsive
|
|
5307
|
+
* - Backdrop automático en mobile drawer mode
|
|
5308
|
+
*
|
|
5309
|
+
* @example
|
|
5310
|
+
* <!-- Mobile drawer (default) -->
|
|
5311
|
+
* <pdm-sidebar [open]="sidebarOpen" (openChange)="sidebarOpen = $event">
|
|
5312
|
+
* <nav>Menu items...</nav>
|
|
5313
|
+
* </pdm-sidebar>
|
|
5314
|
+
*
|
|
5315
|
+
* <!-- Sidebar persistente -->
|
|
5316
|
+
* <pdm-sidebar mobileMode="sidebar" [collapsed]="collapsed">
|
|
5317
|
+
* <nav>Menu items...</nav>
|
|
5318
|
+
* </pdm-sidebar>
|
|
5319
|
+
*/
|
|
3895
5320
|
class PdmSidebarComponent {
|
|
3896
5321
|
constructor() {
|
|
5322
|
+
/**
|
|
5323
|
+
* Mobile behavior: 'drawer' (overlay) o 'sidebar' (persistente)
|
|
5324
|
+
* @default 'drawer'
|
|
5325
|
+
*/
|
|
5326
|
+
this.mobileMode = 'drawer';
|
|
5327
|
+
/**
|
|
5328
|
+
* Collapsed state (solo aplica en mobileMode="sidebar")
|
|
5329
|
+
*/
|
|
3897
5330
|
this.collapsed = false;
|
|
5331
|
+
/**
|
|
5332
|
+
* Open state (solo aplica en mobileMode="drawer")
|
|
5333
|
+
*/
|
|
5334
|
+
this.open = false;
|
|
3898
5335
|
this.className = '';
|
|
5336
|
+
/**
|
|
5337
|
+
* Emite cuando el drawer se cierra (solo en mobileMode="drawer")
|
|
5338
|
+
*/
|
|
5339
|
+
this.openChange = new EventEmitter();
|
|
5340
|
+
}
|
|
5341
|
+
onBackdropClick() {
|
|
5342
|
+
if (this.mobileMode === 'drawer') {
|
|
5343
|
+
this.open = false;
|
|
5344
|
+
this.openChange.emit(false);
|
|
5345
|
+
}
|
|
3899
5346
|
}
|
|
3900
5347
|
}
|
|
3901
5348
|
PdmSidebarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3902
|
-
PdmSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSidebarComponent, selector: "pdm-sidebar", inputs: { collapsed: "collapsed", className: "className" }, ngImport: i0, template: "<aside [ngClass]=\"['h-full border-r border-border bg-background transition-all'
|
|
5349
|
+
PdmSidebarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmSidebarComponent, selector: "pdm-sidebar", inputs: { mobileMode: "mobileMode", collapsed: "collapsed", open: "open", className: "className" }, outputs: { openChange: "openChange" }, ngImport: i0, template: "<!-- Mobile drawer mode -->\n<ng-container *ngIf=\"mobileMode === 'drawer'\">\n <!-- Backdrop -->\n <div\n *ngIf=\"open\"\n class=\"fixed inset-0 z-40 bg-black/50 lg:hidden\"\n (click)=\"onBackdropClick()\"\n ></div>\n \n <!-- Drawer -->\n <aside\n [ngClass]=\"[\n 'fixed inset-y-0 left-0 z-50 h-full w-64 transform border-r border-border bg-background transition-transform duration-300 lg:relative lg:z-auto lg:translate-x-0',\n open ? 'translate-x-0' : '-translate-x-full',\n className\n ]\"\n >\n <ng-content></ng-content>\n </aside>\n</ng-container>\n\n<!-- Sidebar persistente mode -->\n<aside\n *ngIf=\"mobileMode === 'sidebar'\"\n [ngClass]=\"[\n 'h-full border-r border-border bg-background transition-all',\n collapsed ? 'w-14 sm:w-14' : 'w-48 sm:w-56 lg:w-64',\n className\n ]\"\n>\n <ng-content></ng-content>\n</aside>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
3903
5350
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmSidebarComponent, decorators: [{
|
|
3904
5351
|
type: Component,
|
|
3905
|
-
args: [{ selector: 'pdm-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<aside [ngClass]=\"['h-full border-r border-border bg-background transition-all'
|
|
3906
|
-
}], propDecorators: {
|
|
5352
|
+
args: [{ selector: 'pdm-sidebar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- Mobile drawer mode -->\n<ng-container *ngIf=\"mobileMode === 'drawer'\">\n <!-- Backdrop -->\n <div\n *ngIf=\"open\"\n class=\"fixed inset-0 z-40 bg-black/50 lg:hidden\"\n (click)=\"onBackdropClick()\"\n ></div>\n \n <!-- Drawer -->\n <aside\n [ngClass]=\"[\n 'fixed inset-y-0 left-0 z-50 h-full w-64 transform border-r border-border bg-background transition-transform duration-300 lg:relative lg:z-auto lg:translate-x-0',\n open ? 'translate-x-0' : '-translate-x-full',\n className\n ]\"\n >\n <ng-content></ng-content>\n </aside>\n</ng-container>\n\n<!-- Sidebar persistente mode -->\n<aside\n *ngIf=\"mobileMode === 'sidebar'\"\n [ngClass]=\"[\n 'h-full border-r border-border bg-background transition-all',\n collapsed ? 'w-14 sm:w-14' : 'w-48 sm:w-56 lg:w-64',\n className\n ]\"\n>\n <ng-content></ng-content>\n</aside>\n" }]
|
|
5353
|
+
}], propDecorators: { mobileMode: [{
|
|
5354
|
+
type: Input
|
|
5355
|
+
}], collapsed: [{
|
|
5356
|
+
type: Input
|
|
5357
|
+
}], open: [{
|
|
3907
5358
|
type: Input
|
|
3908
5359
|
}], className: [{
|
|
3909
5360
|
type: Input
|
|
5361
|
+
}], openChange: [{
|
|
5362
|
+
type: Output
|
|
3910
5363
|
}] } });
|
|
3911
5364
|
|
|
3912
5365
|
class PdmSkeletonComponent {
|
|
@@ -4073,212 +5526,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4073
5526
|
type: Output
|
|
4074
5527
|
}] } });
|
|
4075
5528
|
|
|
4076
|
-
class PdmTableComponent {
|
|
4077
|
-
constructor(renderer) {
|
|
4078
|
-
this.renderer = renderer;
|
|
4079
|
-
this.variant = 'default';
|
|
4080
|
-
this.reorderRows = false;
|
|
4081
|
-
this.dragHandleSelector = '[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle,[data-auto-drag-handle]';
|
|
4082
|
-
this.className = '';
|
|
4083
|
-
this.rowOrderChange = new EventEmitter();
|
|
4084
|
-
this.cleanupListeners = [];
|
|
4085
|
-
this.draggedRow = null;
|
|
4086
|
-
}
|
|
4087
|
-
ngAfterViewInit() {
|
|
4088
|
-
this.syncReorderBehavior();
|
|
4089
|
-
}
|
|
4090
|
-
ngOnChanges(changes) {
|
|
4091
|
-
if (changes['reorderRows'] || changes['variant']) {
|
|
4092
|
-
this.syncReorderBehavior();
|
|
4093
|
-
}
|
|
4094
|
-
}
|
|
4095
|
-
ngOnDestroy() {
|
|
4096
|
-
this.cleanupReorderBehavior();
|
|
4097
|
-
}
|
|
4098
|
-
get wrapperClasses() {
|
|
4099
|
-
return [
|
|
4100
|
-
'relative w-full overflow-auto',
|
|
4101
|
-
this.variant === 'interactive' ? 'overflow-x-auto overflow-y-hidden rounded-xl border border-border bg-background' : '',
|
|
4102
|
-
this.variant === 'data' ? 'overflow-hidden rounded-md border border-border bg-background' : '',
|
|
4103
|
-
this.className
|
|
4104
|
-
];
|
|
4105
|
-
}
|
|
4106
|
-
get tableClasses() {
|
|
4107
|
-
return [
|
|
4108
|
-
'w-full caption-bottom text-sm',
|
|
4109
|
-
this.variant === 'data'
|
|
4110
|
-
? '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'
|
|
4111
|
-
: '',
|
|
4112
|
-
this.variant === 'interactive'
|
|
4113
|
-
? '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'
|
|
4114
|
-
: ''
|
|
4115
|
-
];
|
|
4116
|
-
}
|
|
4117
|
-
syncReorderBehavior() {
|
|
4118
|
-
this.cleanupReorderBehavior();
|
|
4119
|
-
if (!this.isReorderEnabled) {
|
|
4120
|
-
return;
|
|
4121
|
-
}
|
|
4122
|
-
const tbody = this.getTbody();
|
|
4123
|
-
if (!tbody) {
|
|
4124
|
-
return;
|
|
4125
|
-
}
|
|
4126
|
-
this.setRowsDraggable(tbody, true);
|
|
4127
|
-
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()));
|
|
4128
|
-
this.observer = new MutationObserver(() => this.setRowsDraggable(tbody, true));
|
|
4129
|
-
this.observer.observe(tbody, { childList: true });
|
|
4130
|
-
}
|
|
4131
|
-
cleanupReorderBehavior() {
|
|
4132
|
-
this.cleanupListeners.forEach((dispose) => dispose());
|
|
4133
|
-
this.cleanupListeners = [];
|
|
4134
|
-
if (this.observer) {
|
|
4135
|
-
this.observer.disconnect();
|
|
4136
|
-
this.observer = undefined;
|
|
4137
|
-
}
|
|
4138
|
-
const tbody = this.getTbody();
|
|
4139
|
-
if (tbody) {
|
|
4140
|
-
this.setRowsDraggable(tbody, false);
|
|
4141
|
-
}
|
|
4142
|
-
this.draggedRow = null;
|
|
4143
|
-
}
|
|
4144
|
-
get isReorderEnabled() {
|
|
4145
|
-
return this.reorderRows;
|
|
4146
|
-
}
|
|
4147
|
-
getTbody() {
|
|
4148
|
-
return this.tableElement?.nativeElement.tBodies.item(0) ?? null;
|
|
4149
|
-
}
|
|
4150
|
-
setRowsDraggable(tbody, enabled) {
|
|
4151
|
-
const rows = Array.from(tbody.rows);
|
|
4152
|
-
rows.forEach((row) => {
|
|
4153
|
-
this.syncAutoDragHandle(row, enabled);
|
|
4154
|
-
row.draggable = false;
|
|
4155
|
-
if (!enabled) {
|
|
4156
|
-
delete row.dataset['dragging'];
|
|
4157
|
-
delete row.dataset['dragArmed'];
|
|
4158
|
-
}
|
|
4159
|
-
});
|
|
4160
|
-
}
|
|
4161
|
-
syncAutoDragHandle(row, enabled) {
|
|
4162
|
-
const firstCell = row.cells.item(0);
|
|
4163
|
-
if (!firstCell) {
|
|
4164
|
-
return;
|
|
4165
|
-
}
|
|
4166
|
-
const existingAutoHandle = firstCell.querySelector('[data-auto-drag-handle]');
|
|
4167
|
-
if (!enabled) {
|
|
4168
|
-
existingAutoHandle?.remove();
|
|
4169
|
-
return;
|
|
4170
|
-
}
|
|
4171
|
-
const hasCustomHandle = !!firstCell.querySelector('[data-drag-handle],[data-slot=row-drag-handle],.row-drag-handle');
|
|
4172
|
-
if (hasCustomHandle || existingAutoHandle) {
|
|
4173
|
-
return;
|
|
4174
|
-
}
|
|
4175
|
-
const button = this.renderer.createElement('button');
|
|
4176
|
-
this.renderer.setAttribute(button, 'type', 'button');
|
|
4177
|
-
this.renderer.setAttribute(button, 'aria-label', 'Drag row');
|
|
4178
|
-
this.renderer.setAttribute(button, 'data-auto-drag-handle', 'true');
|
|
4179
|
-
this.renderer.addClass(button, 'inline-flex');
|
|
4180
|
-
this.renderer.addClass(button, 'h-7');
|
|
4181
|
-
this.renderer.addClass(button, 'w-7');
|
|
4182
|
-
this.renderer.addClass(button, 'items-center');
|
|
4183
|
-
this.renderer.addClass(button, 'justify-center');
|
|
4184
|
-
this.renderer.addClass(button, 'cursor-grab');
|
|
4185
|
-
this.renderer.addClass(button, 'active:cursor-grabbing');
|
|
4186
|
-
this.renderer.addClass(button, 'text-muted-foreground');
|
|
4187
|
-
const dots = this.renderer.createElement('span');
|
|
4188
|
-
this.renderer.addClass(dots, 'text-sm');
|
|
4189
|
-
this.renderer.addClass(dots, 'leading-none');
|
|
4190
|
-
this.renderer.setProperty(dots, 'textContent', '⋮⋮');
|
|
4191
|
-
this.renderer.appendChild(button, dots);
|
|
4192
|
-
this.renderer.insertBefore(firstCell, button, firstCell.firstChild);
|
|
4193
|
-
}
|
|
4194
|
-
onDragStart(event) {
|
|
4195
|
-
const target = event.target;
|
|
4196
|
-
const row = target?.closest('tr');
|
|
4197
|
-
if (!row) {
|
|
4198
|
-
return;
|
|
4199
|
-
}
|
|
4200
|
-
const handle = target?.closest(this.dragHandleSelector);
|
|
4201
|
-
const isArmed = row.dataset['dragArmed'] === 'true';
|
|
4202
|
-
if ((!handle || !row.contains(handle)) && !isArmed) {
|
|
4203
|
-
event.preventDefault();
|
|
4204
|
-
return;
|
|
4205
|
-
}
|
|
4206
|
-
this.draggedRow = row;
|
|
4207
|
-
this.draggedRow.dataset['dragging'] = 'true';
|
|
4208
|
-
if (event.dataTransfer) {
|
|
4209
|
-
event.dataTransfer.effectAllowed = 'move';
|
|
4210
|
-
event.dataTransfer.setData('text/plain', '');
|
|
4211
|
-
}
|
|
4212
|
-
}
|
|
4213
|
-
onDragOver(event, tbody) {
|
|
4214
|
-
if (!this.draggedRow) {
|
|
4215
|
-
return;
|
|
4216
|
-
}
|
|
4217
|
-
event.preventDefault();
|
|
4218
|
-
const target = event.target;
|
|
4219
|
-
const targetRow = target?.closest('tr');
|
|
4220
|
-
if (!targetRow || targetRow === this.draggedRow) {
|
|
4221
|
-
return;
|
|
4222
|
-
}
|
|
4223
|
-
const rect = targetRow.getBoundingClientRect();
|
|
4224
|
-
const shouldInsertBefore = event.clientY < rect.top + rect.height / 2;
|
|
4225
|
-
tbody.insertBefore(this.draggedRow, shouldInsertBefore ? targetRow : targetRow.nextSibling);
|
|
4226
|
-
}
|
|
4227
|
-
onDrop(event) {
|
|
4228
|
-
event.preventDefault();
|
|
4229
|
-
}
|
|
4230
|
-
onDragEnd() {
|
|
4231
|
-
const tbody = this.getTbody();
|
|
4232
|
-
if (tbody) {
|
|
4233
|
-
Array.from(tbody.rows).forEach((row) => {
|
|
4234
|
-
row.draggable = false;
|
|
4235
|
-
delete row.dataset['dragArmed'];
|
|
4236
|
-
});
|
|
4237
|
-
}
|
|
4238
|
-
if (this.draggedRow) {
|
|
4239
|
-
delete this.draggedRow.dataset['dragging'];
|
|
4240
|
-
this.draggedRow = null;
|
|
4241
|
-
}
|
|
4242
|
-
if (!tbody) {
|
|
4243
|
-
return;
|
|
4244
|
-
}
|
|
4245
|
-
const order = Array.from(tbody.rows).map((row, index) => row.getAttribute('data-row-id') || String(index));
|
|
4246
|
-
this.rowOrderChange.emit(order);
|
|
4247
|
-
}
|
|
4248
|
-
armDragFromHandle(event) {
|
|
4249
|
-
const target = event.target;
|
|
4250
|
-
const handle = target?.closest(this.dragHandleSelector);
|
|
4251
|
-
if (!handle) {
|
|
4252
|
-
return;
|
|
4253
|
-
}
|
|
4254
|
-
const row = handle.closest('tr');
|
|
4255
|
-
if (!row) {
|
|
4256
|
-
return;
|
|
4257
|
-
}
|
|
4258
|
-
row.draggable = true;
|
|
4259
|
-
row.dataset['dragArmed'] = 'true';
|
|
4260
|
-
}
|
|
4261
|
-
}
|
|
4262
|
-
PdmTableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component });
|
|
4263
|
-
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 });
|
|
4264
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTableComponent, decorators: [{
|
|
4265
|
-
type: Component,
|
|
4266
|
-
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" }]
|
|
4267
|
-
}], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { variant: [{
|
|
4268
|
-
type: Input
|
|
4269
|
-
}], reorderRows: [{
|
|
4270
|
-
type: Input
|
|
4271
|
-
}], dragHandleSelector: [{
|
|
4272
|
-
type: Input
|
|
4273
|
-
}], className: [{
|
|
4274
|
-
type: Input
|
|
4275
|
-
}], rowOrderChange: [{
|
|
4276
|
-
type: Output
|
|
4277
|
-
}], tableElement: [{
|
|
4278
|
-
type: ViewChild,
|
|
4279
|
-
args: ['tableElement']
|
|
4280
|
-
}] } });
|
|
4281
|
-
|
|
4282
5529
|
class PdmTabsComponent {
|
|
4283
5530
|
constructor(cdr) {
|
|
4284
5531
|
this.cdr = cdr;
|
|
@@ -4296,10 +5543,10 @@ class PdmTabsComponent {
|
|
|
4296
5543
|
}
|
|
4297
5544
|
}
|
|
4298
5545
|
PdmTabsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, deps: [{ token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
4299
|
-
PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div
|
|
5546
|
+
PdmTabsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTabsComponent, selector: "pdm-tabs", inputs: { items: "items", value: "value", className: "className" }, outputs: { valueChange: "valueChange" }, ngImport: i0, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4300
5547
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTabsComponent, decorators: [{
|
|
4301
5548
|
type: Component,
|
|
4302
|
-
args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div
|
|
5549
|
+
args: [{ selector: 'pdm-tabs', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div [ngClass]=\"['w-full', className]\">\n <div\n role=\"tablist\"\n class=\"inline-flex h-8 w-full items-center overflow-x-auto scrollbar-thin rounded-lg bg-muted p-[3px] text-muted-foreground md:w-fit\"\n >\n <button\n *ngFor=\"let item of items\"\n role=\"tab\"\n [attr.aria-selected]=\"value === item.value\"\n [disabled]=\"item.disabled\"\n [ngClass]=\"[\n 'relative inline-flex h-[calc(100%-1px)] appearance-none flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-3 py-0.5 text-sm font-medium transition-all focus-visible:border-ring focus-visible:outline-none focus-visible:outline-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 md:flex-initial md:px-4',\n value === item.value ? 'bg-background text-foreground shadow-sm' : 'bg-transparent text-muted-foreground'\n ]\"\n (click)=\"select(item)\"\n type=\"button\"\n >\n {{ item.label }}\n </button>\n </div>\n <div class=\"mt-4\">\n <ng-content></ng-content>\n </div>\n</div>\n" }]
|
|
4303
5550
|
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }]; }, propDecorators: { items: [{
|
|
4304
5551
|
type: Input
|
|
4305
5552
|
}], value: [{
|
|
@@ -4450,10 +5697,10 @@ class PdmTooltipComponent {
|
|
|
4450
5697
|
}
|
|
4451
5698
|
}
|
|
4452
5699
|
PdmTooltipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
4453
|
-
PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, ngImport: i0, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-
|
|
5700
|
+
PdmTooltipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: PdmTooltipComponent, selector: "pdm-tooltip", inputs: { text: "text", side: "side", className: "className" }, ngImport: i0, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\n", dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
4454
5701
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmTooltipComponent, decorators: [{
|
|
4455
5702
|
type: Component,
|
|
4456
|
-
args: [{ selector: 'pdm-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-
|
|
5703
|
+
args: [{ selector: 'pdm-tooltip', changeDetection: ChangeDetectionStrategy.OnPush, template: "<span class=\"relative inline-flex\" [ngClass]=\"className\" (mouseenter)=\"open = true\" (mouseleave)=\"open = false\" (focusin)=\"open = true\" (focusout)=\"open = false\">\n <ng-content></ng-content>\n <span *ngIf=\"open\" [ngClass]=\"['pointer-events-none absolute z-[70] overflow-hidden rounded-md bg-foreground px-3 py-1.5 text-xs text-background animate-in fade-in-0 zoom-in-95', positionClass]\">\n {{ text }}\n </span>\n</span>\n" }]
|
|
4457
5704
|
}], propDecorators: { text: [{
|
|
4458
5705
|
type: Input
|
|
4459
5706
|
}], side: [{
|
|
@@ -4484,6 +5731,7 @@ const COMPONENTS = [
|
|
|
4484
5731
|
PdmDataTableComponent,
|
|
4485
5732
|
PdmDatePickerComponent,
|
|
4486
5733
|
PdmDialogComponent,
|
|
5734
|
+
PdmDraggableTableComponent,
|
|
4487
5735
|
PdmDropdownMenuComponent,
|
|
4488
5736
|
PdmDrawerComponent,
|
|
4489
5737
|
PdmEmptyComponent,
|
|
@@ -4500,6 +5748,7 @@ const COMPONENTS = [
|
|
|
4500
5748
|
PdmMenubarComponent,
|
|
4501
5749
|
PdmNativeSelectComponent,
|
|
4502
5750
|
PdmNavigationMenuComponent,
|
|
5751
|
+
PdmOutsideClickDirective,
|
|
4503
5752
|
PdmPaginationComponent,
|
|
4504
5753
|
PdmPopoverComponent,
|
|
4505
5754
|
PdmProgressComponent,
|
|
@@ -4546,6 +5795,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4546
5795
|
PdmDataTableComponent,
|
|
4547
5796
|
PdmDatePickerComponent,
|
|
4548
5797
|
PdmDialogComponent,
|
|
5798
|
+
PdmDraggableTableComponent,
|
|
4549
5799
|
PdmDropdownMenuComponent,
|
|
4550
5800
|
PdmDrawerComponent,
|
|
4551
5801
|
PdmEmptyComponent,
|
|
@@ -4562,6 +5812,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4562
5812
|
PdmMenubarComponent,
|
|
4563
5813
|
PdmNativeSelectComponent,
|
|
4564
5814
|
PdmNavigationMenuComponent,
|
|
5815
|
+
PdmOutsideClickDirective,
|
|
4565
5816
|
PdmPaginationComponent,
|
|
4566
5817
|
PdmPopoverComponent,
|
|
4567
5818
|
PdmProgressComponent,
|
|
@@ -4603,6 +5854,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4603
5854
|
PdmDataTableComponent,
|
|
4604
5855
|
PdmDatePickerComponent,
|
|
4605
5856
|
PdmDialogComponent,
|
|
5857
|
+
PdmDraggableTableComponent,
|
|
4606
5858
|
PdmDropdownMenuComponent,
|
|
4607
5859
|
PdmDrawerComponent,
|
|
4608
5860
|
PdmEmptyComponent,
|
|
@@ -4619,6 +5871,7 @@ PdmUiKitModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version:
|
|
|
4619
5871
|
PdmMenubarComponent,
|
|
4620
5872
|
PdmNativeSelectComponent,
|
|
4621
5873
|
PdmNavigationMenuComponent,
|
|
5874
|
+
PdmOutsideClickDirective,
|
|
4622
5875
|
PdmPaginationComponent,
|
|
4623
5876
|
PdmPopoverComponent,
|
|
4624
5877
|
PdmProgressComponent,
|
|
@@ -4654,5 +5907,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
4654
5907
|
* Generated bundle index. Do not edit.
|
|
4655
5908
|
*/
|
|
4656
5909
|
|
|
4657
|
-
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, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, createFlexiblePositionStrategy };
|
|
5910
|
+
export { BREAKPOINTS, PdmAccordionComponent, PdmAlertComponent, PdmAlertDialogComponent, PdmAspectRatioComponent, PdmAvatarComponent, PdmBadgeComponent, PdmBreadcrumbComponent, PdmButtonComponent, PdmButtonGroupComponent, PdmCalendarComponent, PdmCardComponent, PdmCarouselComponent, PdmChartComponent, PdmCheckboxComponent, PdmCollapsibleComponent, PdmComboboxComponent, PdmCommandComponent, PdmContextMenuComponent, PdmDataTableComponent, PdmDatePickerComponent, PdmDialogComponent, PdmDraggableTableComponent, PdmDrawerComponent, PdmDropdownMenuComponent, PdmEmptyComponent, PdmFieldComponent, PdmHoverCardComponent, PdmIconComponent, PdmInputComponent, PdmInputGroupComponent, PdmInputOtpComponent, PdmInputPasswordComponent, PdmItemComponent, PdmKbdComponent, PdmLabelComponent, PdmMenubarComponent, PdmNativeSelectComponent, PdmNavigationMenuComponent, PdmOutsideClickDirective, PdmPaginationComponent, PdmPopoverComponent, PdmProgressComponent, PdmRadioGroupComponent, PdmScrollAreaComponent, PdmSelectComponent, PdmSelectOptionDirective, PdmSeparatorComponent, PdmSheetComponent, PdmSidebarComponent, PdmSkeletonComponent, PdmSliderComponent, PdmSonnerComponent, PdmSpinnerComponent, PdmSwitchComponent, PdmTableComponent, PdmTabsComponent, PdmTextareaComponent, PdmToggleComponent, PdmToggleGroupComponent, PdmTooltipComponent, PdmUiKitModule, RESPONSIVE_CONTAINER, RESPONSIVE_DISPLAY, TABLE_RESPONSIVE, Z_INDEX, createFlexiblePositionStrategy, logZIndexStack, overflowResponsive, responsive, spacingResponsive, widthResponsive };
|
|
4658
5911
|
//# sourceMappingURL=pdm-ui-kit.mjs.map
|