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