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/README.md
CHANGED
|
@@ -2,6 +2,17 @@
|
|
|
2
2
|
|
|
3
3
|
Librería de componentes UI para Angular (13, 14 y 15), construida sobre patrones visuales del **Figma de shadcn/ui** y adaptada para el ecosistema de Corelusa.
|
|
4
4
|
|
|
5
|
+
## ✨ What's New in v0.2.0
|
|
6
|
+
|
|
7
|
+
- 🎯 **Responsive by default** — Todas las tablas y dialogs manejan mobile correctamente
|
|
8
|
+
- 🔧 **Generic data-table** — Configurá columnas para cualquier tipo de dato
|
|
9
|
+
- 📦 **Separated concerns** — Drag & drop ahora en `pdm-draggable-table`
|
|
10
|
+
- 🚀 **Responsive utilities** — Sistema centralizado de breakpoints y helpers
|
|
11
|
+
- 📱 **Dialog/Drawer/Sheet mejorados** — Fullscreen mobile, modal/panel desktop
|
|
12
|
+
- 🎨 **Tamaños configurables** — sm, md, lg, xl en todos los componentes overlay
|
|
13
|
+
|
|
14
|
+
➡️ **[Ver Migration Guide](./MIGRATION.md)** si estás actualizando desde v0.1.x
|
|
15
|
+
|
|
5
16
|
## Base de diseño
|
|
6
17
|
|
|
7
18
|
Este kit está **basado en el Figma de shadcn/ui** y mantiene una estructura de estilos por tokens CSS (por ejemplo: `--background`, `--foreground`, `--primary`, `--border`, `--ring`, `--radius`).
|
|
@@ -74,6 +85,112 @@ tabs = [
|
|
|
74
85
|
activeTab = 'general';
|
|
75
86
|
```
|
|
76
87
|
|
|
88
|
+
#### Table (responsive)
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<!-- Tabla simple con scroll horizontal en mobile -->
|
|
92
|
+
<pdm-table variant="interactive" responsiveStrategy="scroll">
|
|
93
|
+
<thead>
|
|
94
|
+
<tr>
|
|
95
|
+
<th>Name</th>
|
|
96
|
+
<th>Email</th>
|
|
97
|
+
<th>Role</th>
|
|
98
|
+
</tr>
|
|
99
|
+
</thead>
|
|
100
|
+
<tbody>
|
|
101
|
+
<tr>
|
|
102
|
+
<td>John Doe</td>
|
|
103
|
+
<td>john@example.com</td>
|
|
104
|
+
<td>Admin</td>
|
|
105
|
+
</tr>
|
|
106
|
+
</tbody>
|
|
107
|
+
</pdm-table>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
#### Data Table (genérico)
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import { PdmDataTableColumn } from 'pdm-ui-kit';
|
|
114
|
+
|
|
115
|
+
interface User {
|
|
116
|
+
id: number;
|
|
117
|
+
name: string;
|
|
118
|
+
email: string;
|
|
119
|
+
role: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
columns: PdmDataTableColumn<User>[] = [
|
|
123
|
+
{ key: 'name', label: 'Name', sortable: true },
|
|
124
|
+
{ key: 'email', label: 'Email', sortable: true },
|
|
125
|
+
{ key: 'role', label: 'Role', hideOnMobile: true }
|
|
126
|
+
];
|
|
127
|
+
|
|
128
|
+
users: User[] = [
|
|
129
|
+
{ id: 1, name: 'John', email: 'john@example.com', role: 'Admin' },
|
|
130
|
+
{ id: 2, name: 'Jane', email: 'jane@example.com', role: 'User' }
|
|
131
|
+
];
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
```html
|
|
135
|
+
<pdm-data-table
|
|
136
|
+
[columns]="columns"
|
|
137
|
+
[rows]="users"
|
|
138
|
+
[selectable]="true"
|
|
139
|
+
responsiveStrategy="scroll"
|
|
140
|
+
(selectionChange)="onSelect($event)">
|
|
141
|
+
</pdm-data-table>
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Draggable Table
|
|
145
|
+
|
|
146
|
+
```html
|
|
147
|
+
<pdm-draggable-table
|
|
148
|
+
variant="interactive"
|
|
149
|
+
[reorderRows]="true"
|
|
150
|
+
(rowOrderChange)="onOrderChange($event)">
|
|
151
|
+
<tbody>
|
|
152
|
+
<tr data-row-id="1"><td>Task 1</td></tr>
|
|
153
|
+
<tr data-row-id="2"><td>Task 2</td></tr>
|
|
154
|
+
<tr data-row-id="3"><td>Task 3</td></tr>
|
|
155
|
+
</tbody>
|
|
156
|
+
</pdm-draggable-table>
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
#### Dialog (responsive)
|
|
160
|
+
|
|
161
|
+
```html
|
|
162
|
+
<!-- Fullscreen en mobile, modal en desktop -->
|
|
163
|
+
<pdm-dialog
|
|
164
|
+
[open]="isOpen"
|
|
165
|
+
size="responsive"
|
|
166
|
+
title="Edit Profile"
|
|
167
|
+
description="Make changes to your profile here"
|
|
168
|
+
(openChange)="isOpen = $event"
|
|
169
|
+
(primaryAction)="onSave()">
|
|
170
|
+
<div class="space-y-4">
|
|
171
|
+
<input type="text" placeholder="Name" class="w-full" />
|
|
172
|
+
<input type="email" placeholder="Email" class="w-full" />
|
|
173
|
+
</div>
|
|
174
|
+
</pdm-dialog>
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
#### Drawer (side panel)
|
|
178
|
+
|
|
179
|
+
```html
|
|
180
|
+
<!-- Bottom sheet en mobile, side panel en desktop -->
|
|
181
|
+
<pdm-drawer
|
|
182
|
+
[open]="isOpen"
|
|
183
|
+
position="right"
|
|
184
|
+
size="md"
|
|
185
|
+
title="Settings"
|
|
186
|
+
(openChange)="isOpen = $event">
|
|
187
|
+
<div class="space-y-4">
|
|
188
|
+
<h4>Preferences</h4>
|
|
189
|
+
<p>Configure your settings here</p>
|
|
190
|
+
</div>
|
|
191
|
+
</pdm-drawer>
|
|
192
|
+
```
|
|
193
|
+
|
|
77
194
|
#### Iconos
|
|
78
195
|
|
|
79
196
|
```html
|
|
@@ -112,6 +229,52 @@ Tipos soportados en `pdm-chart`:
|
|
|
112
229
|
- `radial`
|
|
113
230
|
- `tooltips`
|
|
114
231
|
|
|
232
|
+
## Responsive Design
|
|
233
|
+
|
|
234
|
+
Todos los componentes siguen **mobile-first approach**:
|
|
235
|
+
|
|
236
|
+
| Componente | Mobile Behavior | Desktop Behavior |
|
|
237
|
+
|------------|----------------|------------------|
|
|
238
|
+
| `pdm-table` | Scroll horizontal | Full width, no scroll |
|
|
239
|
+
| `pdm-data-table` | Oculta columnas opcionales | Muestra todas |
|
|
240
|
+
| `pdm-dialog` | Fullscreen | Modal centrado |
|
|
241
|
+
| `pdm-drawer` | Bottom sheet | Side panel |
|
|
242
|
+
|
|
243
|
+
### Breakpoints
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { BREAKPOINTS } from 'pdm-ui-kit';
|
|
247
|
+
|
|
248
|
+
const breakpoints = {
|
|
249
|
+
sm: '640px', // tablet portrait
|
|
250
|
+
md: '768px', // tablet landscape
|
|
251
|
+
lg: '1024px', // desktop
|
|
252
|
+
xl: '1280px', // large desktop
|
|
253
|
+
'2xl': '1536px' // extra large
|
|
254
|
+
};
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Responsive Utilities
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
import { responsive, overflowResponsive, TABLE_RESPONSIVE } from 'pdm-ui-kit';
|
|
261
|
+
|
|
262
|
+
// Helper para clases responsive
|
|
263
|
+
const classes = responsive({
|
|
264
|
+
default: 'block',
|
|
265
|
+
sm: 'flex',
|
|
266
|
+
lg: 'grid'
|
|
267
|
+
}); // 'block sm:flex lg:grid'
|
|
268
|
+
|
|
269
|
+
// Helper para overflow
|
|
270
|
+
const overflow = overflowResponsive('x', 'scroll', 'auto');
|
|
271
|
+
// 'overflow-x-scroll sm:overflow-x-auto'
|
|
272
|
+
|
|
273
|
+
// Clases pre-definidas para tablas
|
|
274
|
+
const tableClasses = TABLE_RESPONSIVE.scroll.wrapper;
|
|
275
|
+
// 'relative w-full overflow-x-auto'
|
|
276
|
+
```
|
|
277
|
+
|
|
115
278
|
## Theming
|
|
116
279
|
|
|
117
280
|
Los componentes leen los tokens CSS del proyecto consumidor. Define tus variables globales para aplicar tu tema (light/dark o custom branding) sin modificar el kit.
|
|
@@ -122,7 +285,31 @@ Incluye componentes como:
|
|
|
122
285
|
|
|
123
286
|
- `pdm-button`, `pdm-input`, `pdm-textarea`, `pdm-select`
|
|
124
287
|
- `pdm-alert`, `pdm-badge`, `pdm-card`, `pdm-dialog`
|
|
125
|
-
- `pdm-tabs`, `pdm-table`, `pdm-data-table`, `pdm-
|
|
126
|
-
- `pdm-tooltip`, `pdm-popover`, `pdm-dropdown-menu
|
|
288
|
+
- `pdm-tabs`, `pdm-table`, `pdm-data-table`, `pdm-draggable-table`
|
|
289
|
+
- `pdm-chart`, `pdm-tooltip`, `pdm-popover`, `pdm-dropdown-menu`
|
|
290
|
+
- `pdm-sidebar`, `pdm-sheet`, `pdm-drawer`, `pdm-calendar`
|
|
127
291
|
|
|
128
292
|
Y más, todos exportados desde `PdmUiKitModule`.
|
|
293
|
+
|
|
294
|
+
## Documentación
|
|
295
|
+
|
|
296
|
+
- **[Migration Guide](./MIGRATION.md)** — Guía de migración desde v0.1.x
|
|
297
|
+
- **[API Reference](./docs/API.md)** — Documentación completa de todos los componentes (próximamente)
|
|
298
|
+
|
|
299
|
+
## Changelog
|
|
300
|
+
|
|
301
|
+
### v0.2.0 (2024)
|
|
302
|
+
- ✨ Sistema de responsive utilities centralizado
|
|
303
|
+
- ✨ `pdm-table` refactorizado con responsive strategies
|
|
304
|
+
- ✨ `pdm-draggable-table` componente nuevo (drag & drop)
|
|
305
|
+
- ✨ `pdm-data-table` ahora genérico con configuración de columnas
|
|
306
|
+
- ✨ `pdm-dialog` con modo responsive y tamaños configurables
|
|
307
|
+
- ✨ `pdm-drawer` refactorizado con posicionamiento y contenido genérico
|
|
308
|
+
- ✨ `pdm-sheet` con tamaños responsive
|
|
309
|
+
- 🐛 Fix: Tablas rompiendo el width en mobile
|
|
310
|
+
- 🐛 Fix: Dialog/Drawer sin responsive adecuado
|
|
311
|
+
- 📚 Migration guide completo
|
|
312
|
+
- 📚 Documentación mejorada con ejemplos responsive
|
|
313
|
+
|
|
314
|
+
### v0.1.x
|
|
315
|
+
- Componentes base adaptados de shadcn/ui
|
|
@@ -11,35 +11,51 @@ export class PdmAlertDialogComponent {
|
|
|
11
11
|
this.confirmText = 'Continue';
|
|
12
12
|
this.cancelText = 'Cancel';
|
|
13
13
|
this.className = '';
|
|
14
|
+
/** Close when the ESC key is pressed. Default: `true`. */
|
|
15
|
+
this.closeOnEsc = true;
|
|
14
16
|
this.openChange = new EventEmitter();
|
|
15
17
|
this.confirm = new EventEmitter();
|
|
16
18
|
this.cancel = new EventEmitter();
|
|
17
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Returns `true` when at least one consumer listens to `openChange`.
|
|
22
|
+
* - **Controlled** (has observers): parent manages `open` via two-way binding → only emit.
|
|
23
|
+
* - **Uncontrolled** (no observers): we own the `open` state → mutate it locally.
|
|
24
|
+
*/
|
|
25
|
+
get isControlled() {
|
|
26
|
+
return this.openChange.observed;
|
|
27
|
+
}
|
|
18
28
|
onTriggerClick() {
|
|
19
|
-
this.
|
|
29
|
+
if (!this.isControlled) {
|
|
30
|
+
this.open = true;
|
|
31
|
+
}
|
|
20
32
|
this.openChange.emit(true);
|
|
21
33
|
}
|
|
22
34
|
onCancel() {
|
|
23
35
|
this.cancel.emit();
|
|
24
|
-
this.
|
|
36
|
+
if (!this.isControlled) {
|
|
37
|
+
this.open = false;
|
|
38
|
+
}
|
|
25
39
|
this.openChange.emit(false);
|
|
26
40
|
}
|
|
27
41
|
onConfirm() {
|
|
28
42
|
this.confirm.emit();
|
|
29
|
-
this.
|
|
43
|
+
if (!this.isControlled) {
|
|
44
|
+
this.open = false;
|
|
45
|
+
}
|
|
30
46
|
this.openChange.emit(false);
|
|
31
47
|
}
|
|
32
48
|
onEsc() {
|
|
33
|
-
if (this.open) {
|
|
49
|
+
if (this.open && this.closeOnEsc) {
|
|
34
50
|
this.onCancel();
|
|
35
51
|
}
|
|
36
52
|
}
|
|
37
53
|
}
|
|
38
54
|
PdmAlertDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
39
|
-
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-
|
|
55
|
+
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 });
|
|
40
56
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmAlertDialogComponent, decorators: [{
|
|
41
57
|
type: Component,
|
|
42
|
-
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-
|
|
58
|
+
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" }]
|
|
43
59
|
}], propDecorators: { open: [{
|
|
44
60
|
type: Input
|
|
45
61
|
}], showTrigger: [{
|
|
@@ -56,6 +72,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
56
72
|
type: Input
|
|
57
73
|
}], className: [{
|
|
58
74
|
type: Input
|
|
75
|
+
}], closeOnEsc: [{
|
|
76
|
+
type: Input
|
|
59
77
|
}], openChange: [{
|
|
60
78
|
type: Output
|
|
61
79
|
}], confirm: [{
|
|
@@ -66,4 +84,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImpor
|
|
|
66
84
|
type: HostListener,
|
|
67
85
|
args: ['document:keydown.escape']
|
|
68
86
|
}] } });
|
|
69
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
87
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWxlcnQtZGlhbG9nLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hbGVydC1kaWFsb2cvYWxlcnQtZGlhbG9nLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9hbGVydC1kaWFsb2cvYWxlcnQtZGlhbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDOzs7QUFPOUcsTUFBTSxPQUFPLHVCQUF1QjtJQUxwQztRQU1XLFNBQUksR0FBRyxLQUFLLENBQUM7UUFDYixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNwQixnQkFBVyxHQUFHLGFBQWEsQ0FBQztRQUM1QixVQUFLLEdBQUcsMEJBQTBCLENBQUM7UUFDbkMsZ0JBQVcsR0FBRyxFQUFFLENBQUM7UUFDakIsZ0JBQVcsR0FBRyxVQUFVLENBQUM7UUFDekIsZUFBVSxHQUFHLFFBQVEsQ0FBQztRQUN0QixjQUFTLEdBQUcsRUFBRSxDQUFDO1FBRXhCLDBEQUEwRDtRQUNqRCxlQUFVLEdBQUcsSUFBSSxDQUFDO1FBRWpCLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBVyxDQUFDO1FBQ3pDLFlBQU8sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBQ25DLFdBQU0sR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO0tBd0M3QztJQXRDQzs7OztPQUlHO0lBQ0gsSUFBWSxZQUFZO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUM7SUFDbEMsQ0FBQztJQUVELGNBQWM7UUFDWixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztTQUNsQjtRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFRCxRQUFRO1FBQ04sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztTQUNuQjtRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFFRCxTQUFTO1FBQ1AsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRTtZQUN0QixJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQztTQUNuQjtRQUNELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzlCLENBQUM7SUFHRCxLQUFLO1FBQ0gsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDaEMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ2pCO0lBQ0gsQ0FBQzs7b0hBdERVLHVCQUF1Qjt3R0FBdkIsdUJBQXVCLDBhQ1BwQywwbURBeUNBOzJGRGxDYSx1QkFBdUI7a0JBTG5DLFNBQVM7K0JBQ0Usa0JBQWtCLG1CQUVYLHVCQUF1QixDQUFDLE1BQU07OEJBR3RDLElBQUk7c0JBQVosS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBR0csVUFBVTtzQkFBbEIsS0FBSztnQkFFSSxVQUFVO3NCQUFuQixNQUFNO2dCQUNHLE9BQU87c0JBQWhCLE1BQU07Z0JBQ0csTUFBTTtzQkFBZixNQUFNO2dCQW1DUCxLQUFLO3NCQURKLFlBQVk7dUJBQUMseUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncGRtLWFsZXJ0LWRpYWxvZycsXG4gIHRlbXBsYXRlVXJsOiAnLi9hbGVydC1kaWFsb2cuY29tcG9uZW50Lmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBQZG1BbGVydERpYWxvZ0NvbXBvbmVudCB7XG4gIEBJbnB1dCgpIG9wZW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd1RyaWdnZXIgPSBmYWxzZTtcbiAgQElucHV0KCkgdHJpZ2dlclRleHQgPSAnU2hvdyBkaWFsb2cnO1xuICBASW5wdXQoKSB0aXRsZSA9ICdBcmUgeW91IGFic29sdXRlbHkgc3VyZT8nO1xuICBASW5wdXQoKSBkZXNjcmlwdGlvbiA9ICcnO1xuICBASW5wdXQoKSBjb25maXJtVGV4dCA9ICdDb250aW51ZSc7XG4gIEBJbnB1dCgpIGNhbmNlbFRleHQgPSAnQ2FuY2VsJztcbiAgQElucHV0KCkgY2xhc3NOYW1lID0gJyc7XG5cbiAgLyoqIENsb3NlIHdoZW4gdGhlIEVTQyBrZXkgaXMgcHJlc3NlZC4gRGVmYXVsdDogYHRydWVgLiAqL1xuICBASW5wdXQoKSBjbG9zZU9uRXNjID0gdHJ1ZTtcblxuICBAT3V0cHV0KCkgb3BlbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcbiAgQE91dHB1dCgpIGNvbmZpcm0gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBjYW5jZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYHRydWVgIHdoZW4gYXQgbGVhc3Qgb25lIGNvbnN1bWVyIGxpc3RlbnMgdG8gYG9wZW5DaGFuZ2VgLlxuICAgKiAtICoqQ29udHJvbGxlZCoqIChoYXMgb2JzZXJ2ZXJzKTogcGFyZW50IG1hbmFnZXMgYG9wZW5gIHZpYSB0d28td2F5IGJpbmRpbmcg4oaSIG9ubHkgZW1pdC5cbiAgICogLSAqKlVuY29udHJvbGxlZCoqIChubyBvYnNlcnZlcnMpOiB3ZSBvd24gdGhlIGBvcGVuYCBzdGF0ZSDihpIgbXV0YXRlIGl0IGxvY2FsbHkuXG4gICAqL1xuICBwcml2YXRlIGdldCBpc0NvbnRyb2xsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3BlbkNoYW5nZS5vYnNlcnZlZDtcbiAgfVxuXG4gIG9uVHJpZ2dlckNsaWNrKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0NvbnRyb2xsZWQpIHtcbiAgICAgIHRoaXMub3BlbiA9IHRydWU7XG4gICAgfVxuICAgIHRoaXMub3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuICB9XG5cbiAgb25DYW5jZWwoKTogdm9pZCB7XG4gICAgdGhpcy5jYW5jZWwuZW1pdCgpO1xuICAgIGlmICghdGhpcy5pc0NvbnRyb2xsZWQpIHtcbiAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgIH1cbiAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChmYWxzZSk7XG4gIH1cblxuICBvbkNvbmZpcm0oKTogdm9pZCB7XG4gICAgdGhpcy5jb25maXJtLmVtaXQoKTtcbiAgICBpZiAoIXRoaXMuaXNDb250cm9sbGVkKSB7XG4gICAgICB0aGlzLm9wZW4gPSBmYWxzZTtcbiAgICB9XG4gICAgdGhpcy5vcGVuQ2hhbmdlLmVtaXQoZmFsc2UpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5lc2NhcGUnKVxuICBvbkVzYygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vcGVuICYmIHRoaXMuY2xvc2VPbkVzYykge1xuICAgICAgdGhpcy5vbkNhbmNlbCgpO1xuICAgIH1cbiAgfVxufVxuIiwiPGJ1dHRvblxuICAqbmdJZj1cInNob3dUcmlnZ2VyICYmICFvcGVuXCJcbiAgdHlwZT1cImJ1dHRvblwiXG4gIGNsYXNzPVwiaW5saW5lLWZsZXggaC05IGFwcGVhcmFuY2Utbm9uZSBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1tZCBib3JkZXIgYm9yZGVyLWlucHV0IGJnLWJhY2tncm91bmQgcHgtNCBweS0yIHRleHQtc20gZm9udC1tZWRpdW0gdGV4dC1mb3JlZ3JvdW5kIHNoYWRvdy1zbVwiXG4gIChjbGljayk9XCJvblRyaWdnZXJDbGljaygpXCJcbj5cbiAge3sgdHJpZ2dlclRleHQgfX1cbjwvYnV0dG9uPlxuXG48ZGl2ICpuZ0lmPVwib3BlblwiIGNsYXNzPVwiZml4ZWQgaW5zZXQtMCB6LTUwIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHAtNVwiPlxuICA8ZGl2IGNsYXNzPVwiYWJzb2x1dGUgaW5zZXQtMCBiZy1mb3JlZ3JvdW5kLzMwXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIj48L2Rpdj5cbiAgPHNlY3Rpb25cbiAgICByb2xlPVwiYWxlcnRkaWFsb2dcIlxuICAgIGFyaWEtbW9kYWw9XCJ0cnVlXCJcbiAgICBbbmdDbGFzc109XCJbXG4gICAgICAncmVsYXRpdmUgei1bNjBdIHctZnVsbCBtYXgtdy1sZyByb3VuZGVkLWxnIGJvcmRlciBib3JkZXItYm9yZGVyIGJnLWJhY2tncm91bmQgcC02IHRleHQtZm9yZWdyb3VuZCBzaGFkb3ctbGcnLFxuICAgICAgY2xhc3NOYW1lXG4gICAgXVwiXG4gID5cbiAgICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbCBnYXAtMlwiPlxuICAgICAgPGgyIGNsYXNzPVwibS0wIHRleHQtbGcgZm9udC1zZW1pYm9sZCBsZWFkaW5nLW5vbmUgdHJhY2tpbmctdGlnaHRcIj57eyB0aXRsZSB9fTwvaDI+XG4gICAgICA8cCAqbmdJZj1cImRlc2NyaXB0aW9uXCIgY2xhc3M9XCJtLTAgdGV4dC1zbSB0ZXh0LW11dGVkLWZvcmVncm91bmRcIj57eyBkZXNjcmlwdGlvbiB9fTwvcD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXQtNCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWVuZCBnYXAtMlwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBoLTkgYXBwZWFyYW5jZS1ub25lIGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciByb3VuZGVkLW1kIGJvcmRlciBib3JkZXItaW5wdXQgYmctYmFja2dyb3VuZCBweC00IHB5LTIgdGV4dC1zbSBmb250LW1lZGl1bSB0ZXh0LWZvcmVncm91bmQgc2hhZG93LXNtXCJcbiAgICAgICAgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIlxuICAgICAgPlxuICAgICAgICB7eyBjYW5jZWxUZXh0IH19XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiaW5saW5lLWZsZXggaC05IGFwcGVhcmFuY2Utbm9uZSBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1tZCBiZy1wcmltYXJ5IHB4LTQgcHktMiB0ZXh0LXNtIGZvbnQtbWVkaXVtIHRleHQtcHJpbWFyeS1mb3JlZ3JvdW5kIHNoYWRvdy1zbVwiXG4gICAgICAgIChjbGljayk9XCJvbkNvbmZpcm0oKVwiXG4gICAgICA+XG4gICAgICAgIHt7IGNvbmZpcm1UZXh0IH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9zZWN0aW9uPlxuPC9kaXY+XG4iXX0=
|
|
@@ -1,29 +1,62 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, Component, Input } from '@angular/core';
|
|
2
2
|
import * as i0 from "@angular/core";
|
|
3
3
|
import * as i1 from "@angular/common";
|
|
4
|
+
/**
|
|
5
|
+
* Breadcrumb component con soporte responsive
|
|
6
|
+
*
|
|
7
|
+
* MEJORADO en v0.2.0:
|
|
8
|
+
* - Modo responsive real con overflow-x-auto
|
|
9
|
+
* - Collapse inteligente en mobile
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <pdm-breadcrumb
|
|
13
|
+
* mode="responsive"
|
|
14
|
+
* [items]="['Home', 'Products', 'Electronics', 'Laptops']">
|
|
15
|
+
* </pdm-breadcrumb>
|
|
16
|
+
*/
|
|
4
17
|
export class PdmBreadcrumbComponent {
|
|
5
18
|
constructor() {
|
|
6
19
|
this.mode = 'link-component';
|
|
7
20
|
this.items = ['Home', 'Components', 'Breadcrumb'];
|
|
8
21
|
this.className = '';
|
|
22
|
+
/**
|
|
23
|
+
* Cantidad mínima de items para mostrar en mobile cuando mode="responsive"
|
|
24
|
+
* Default: 2 (primer y último item)
|
|
25
|
+
*/
|
|
26
|
+
this.minItemsMobile = 2;
|
|
9
27
|
}
|
|
10
28
|
get renderedItems() {
|
|
11
|
-
if (
|
|
29
|
+
if (this.mode === 'collapsed' && this.items.length > 3) {
|
|
12
30
|
return [this.items[0], '...', this.items[this.items.length - 2], this.items[this.items.length - 1]];
|
|
13
31
|
}
|
|
32
|
+
// Responsive mode: no collapse en el TS, se maneja en el template con CSS
|
|
14
33
|
return this.items;
|
|
15
34
|
}
|
|
35
|
+
/**
|
|
36
|
+
* Determina si un item debe estar visible en mobile (modo responsive)
|
|
37
|
+
*/
|
|
38
|
+
shouldShowInMobile(index) {
|
|
39
|
+
if (this.mode !== 'responsive')
|
|
40
|
+
return true;
|
|
41
|
+
const totalItems = this.items.length;
|
|
42
|
+
if (totalItems <= this.minItemsMobile)
|
|
43
|
+
return true;
|
|
44
|
+
// Siempre mostrar primero y último
|
|
45
|
+
return index === 0 || index === totalItems - 1;
|
|
46
|
+
}
|
|
16
47
|
}
|
|
17
48
|
PdmBreadcrumbComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
18
|
-
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'
|
|
49
|
+
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 });
|
|
19
50
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: PdmBreadcrumbComponent, decorators: [{
|
|
20
51
|
type: Component,
|
|
21
|
-
args: [{ selector: 'pdm-breadcrumb', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav\n aria-label=\"breadcrumb\"\n [ngClass]=\"['inline-flex items-center gap-1.5 text-sm'
|
|
52
|
+
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" }]
|
|
22
53
|
}], propDecorators: { mode: [{
|
|
23
54
|
type: Input
|
|
24
55
|
}], items: [{
|
|
25
56
|
type: Input
|
|
26
57
|
}], className: [{
|
|
27
58
|
type: Input
|
|
59
|
+
}], minItemsMobile: [{
|
|
60
|
+
type: Input
|
|
28
61
|
}] } });
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
62
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJlYWRjcnVtYi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbGliL2NvbXBvbmVudHMvYnJlYWRjcnVtYi9icmVhZGNydW1iLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9icmVhZGNydW1iL2JyZWFkY3J1bWIuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxlQUFlLENBQUM7OztBQVMxRTs7Ozs7Ozs7Ozs7O0dBWUc7QUFNSCxNQUFNLE9BQU8sc0JBQXNCO0lBTG5DO1FBTVcsU0FBSSxHQUFzQixnQkFBZ0IsQ0FBQztRQUMzQyxVQUFLLEdBQWEsQ0FBQyxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ3ZELGNBQVMsR0FBRyxFQUFFLENBQUM7UUFFeEI7OztXQUdHO1FBQ00sbUJBQWMsR0FBRyxDQUFDLENBQUM7S0F1QjdCO0lBckJDLElBQUksYUFBYTtRQUNmLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3RELE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNyRztRQUVELDBFQUEwRTtRQUMxRSxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsa0JBQWtCLENBQUMsS0FBYTtRQUM5QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssWUFBWTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBRTVDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQ3JDLElBQUksVUFBVSxJQUFJLElBQUksQ0FBQyxjQUFjO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFFbkQsbUNBQW1DO1FBQ25DLE9BQU8sS0FBSyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssVUFBVSxHQUFHLENBQUMsQ0FBQztJQUNqRCxDQUFDOzttSEEvQlUsc0JBQXNCO3VHQUF0QixzQkFBc0IsMEpDM0JuQyxtckZBb0VBOzJGRHpDYSxzQkFBc0I7a0JBTGxDLFNBQVM7K0JBQ0UsZ0JBQWdCLG1CQUVULHVCQUF1QixDQUFDLE1BQU07OEJBR3RDLElBQUk7c0JBQVosS0FBSztnQkFDRyxLQUFLO3NCQUFiLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFNRyxjQUFjO3NCQUF0QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5wdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuZXhwb3J0IHR5cGUgUGRtQnJlYWRjcnVtYk1vZGUgPVxuICB8ICdjdXN0b20tc2VwYXJhdG9yJ1xuICB8ICdkcm9wZG93bidcbiAgfCAnY29sbGFwc2VkJ1xuICB8ICdsaW5rLWNvbXBvbmVudCdcbiAgfCAncmVzcG9uc2l2ZSc7XG5cbi8qKlxuICogQnJlYWRjcnVtYiBjb21wb25lbnQgY29uIHNvcG9ydGUgcmVzcG9uc2l2ZVxuICogXG4gKiBNRUpPUkFETyBlbiB2MC4yLjA6XG4gKiAtIE1vZG8gcmVzcG9uc2l2ZSByZWFsIGNvbiBvdmVyZmxvdy14LWF1dG9cbiAqIC0gQ29sbGFwc2UgaW50ZWxpZ2VudGUgZW4gbW9iaWxlXG4gKiBcbiAqIEBleGFtcGxlXG4gKiA8cGRtLWJyZWFkY3J1bWJcbiAqICAgbW9kZT1cInJlc3BvbnNpdmVcIlxuICogICBbaXRlbXNdPVwiWydIb21lJywgJ1Byb2R1Y3RzJywgJ0VsZWN0cm9uaWNzJywgJ0xhcHRvcHMnXVwiPlxuICogPC9wZG0tYnJlYWRjcnVtYj5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncGRtLWJyZWFkY3J1bWInLFxuICB0ZW1wbGF0ZVVybDogJy4vYnJlYWRjcnVtYi5jb21wb25lbnQuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIFBkbUJyZWFkY3J1bWJDb21wb25lbnQge1xuICBASW5wdXQoKSBtb2RlOiBQZG1CcmVhZGNydW1iTW9kZSA9ICdsaW5rLWNvbXBvbmVudCc7XG4gIEBJbnB1dCgpIGl0ZW1zOiBzdHJpbmdbXSA9IFsnSG9tZScsICdDb21wb25lbnRzJywgJ0JyZWFkY3J1bWInXTtcbiAgQElucHV0KCkgY2xhc3NOYW1lID0gJyc7XG4gIFxuICAvKipcbiAgICogQ2FudGlkYWQgbcOtbmltYSBkZSBpdGVtcyBwYXJhIG1vc3RyYXIgZW4gbW9iaWxlIGN1YW5kbyBtb2RlPVwicmVzcG9uc2l2ZVwiXG4gICAqIERlZmF1bHQ6IDIgKHByaW1lciB5IMO6bHRpbW8gaXRlbSlcbiAgICovXG4gIEBJbnB1dCgpIG1pbkl0ZW1zTW9iaWxlID0gMjtcblxuICBnZXQgcmVuZGVyZWRJdGVtcygpOiBzdHJpbmdbXSB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2NvbGxhcHNlZCcgJiYgdGhpcy5pdGVtcy5sZW5ndGggPiAzKSB7XG4gICAgICByZXR1cm4gW3RoaXMuaXRlbXNbMF0sICcuLi4nLCB0aGlzLml0ZW1zW3RoaXMuaXRlbXMubGVuZ3RoIC0gMl0sIHRoaXMuaXRlbXNbdGhpcy5pdGVtcy5sZW5ndGggLSAxXV07XG4gICAgfVxuICAgIFxuICAgIC8vIFJlc3BvbnNpdmUgbW9kZTogbm8gY29sbGFwc2UgZW4gZWwgVFMsIHNlIG1hbmVqYSBlbiBlbCB0ZW1wbGF0ZSBjb24gQ1NTXG4gICAgcmV0dXJuIHRoaXMuaXRlbXM7XG4gIH1cbiAgXG4gIC8qKlxuICAgKiBEZXRlcm1pbmEgc2kgdW4gaXRlbSBkZWJlIGVzdGFyIHZpc2libGUgZW4gbW9iaWxlIChtb2RvIHJlc3BvbnNpdmUpXG4gICAqL1xuICBzaG91bGRTaG93SW5Nb2JpbGUoaW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm1vZGUgIT09ICdyZXNwb25zaXZlJykgcmV0dXJuIHRydWU7XG4gICAgXG4gICAgY29uc3QgdG90YWxJdGVtcyA9IHRoaXMuaXRlbXMubGVuZ3RoO1xuICAgIGlmICh0b3RhbEl0ZW1zIDw9IHRoaXMubWluSXRlbXNNb2JpbGUpIHJldHVybiB0cnVlO1xuICAgIFxuICAgIC8vIFNpZW1wcmUgbW9zdHJhciBwcmltZXJvIHkgw7psdGltb1xuICAgIHJldHVybiBpbmRleCA9PT0gMCB8fCBpbmRleCA9PT0gdG90YWxJdGVtcyAtIDE7XG4gIH1cbn1cbiIsIjxuYXZcbiAgYXJpYS1sYWJlbD1cImJyZWFkY3J1bWJcIlxuICBbbmdDbGFzc109XCJbXG4gICAgJ2lubGluZS1mbGV4IGl0ZW1zLWNlbnRlciBnYXAtMS41IHRleHQtc20nLFxuICAgIG1vZGUgPT09ICdyZXNwb25zaXZlJyA/ICdvdmVyZmxvdy14LWF1dG8gbWF4LXctZnVsbCBwYi0xIHNjcm9sbGJhci10aGluJyA6ICcnLFxuICAgIGNsYXNzTmFtZVxuICBdXCJcbj5cbiAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgaXRlbSBvZiByZW5kZXJlZEl0ZW1zOyBsZXQgaSA9IGluZGV4OyBsZXQgbGFzdCA9IGxhc3RcIj5cbiAgICA8IS0tIEl0ZW0gdGV4dCAtLT5cbiAgICA8c3BhbiBcbiAgICAgIFtuZ0NsYXNzXT1cIltcbiAgICAgICAgbGFzdCA/ICd0ZXh0LWZvcmVncm91bmQgZm9udC1tZWRpdW0nIDogJ3RleHQtbXV0ZWQtZm9yZWdyb3VuZCBob3Zlcjp0ZXh0LWZvcmVncm91bmQgdHJhbnNpdGlvbi1jb2xvcnMgY3Vyc29yLXBvaW50ZXInLFxuICAgICAgICBtb2RlID09PSAncmVzcG9uc2l2ZScgJiYgIXNob3VsZFNob3dJbk1vYmlsZShpKSA/ICdoaWRkZW4gc206aW5saW5lJyA6ICcnLFxuICAgICAgICAnd2hpdGVzcGFjZS1ub3dyYXAnXG4gICAgICBdXCI+XG4gICAgICB7eyBpdGVtIH19XG4gICAgPC9zcGFuPlxuXG4gICAgPCEtLSBTZXBhcmF0b3IgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFsYXN0XCI+XG4gICAgICA8c3BhbiBcbiAgICAgICAgW25nQ2xhc3NdPVwiW1xuICAgICAgICAgICdpbmxpbmUtZmxleCBoLTYgdy02IGZsZXgtc2hyaW5rLTAgaXRlbXMtY2VudGVyIGp1c3RpZnktY2VudGVyIHRleHQtbXV0ZWQtZm9yZWdyb3VuZCcsXG4gICAgICAgICAgbW9kZSA9PT0gJ3Jlc3BvbnNpdmUnICYmICFzaG91bGRTaG93SW5Nb2JpbGUoaSkgJiYgIXNob3VsZFNob3dJbk1vYmlsZShpICsgMSkgPyAnaGlkZGVuIHNtOmlubGluZS1mbGV4JyA6ICcnXG4gICAgICAgIF1cIiBcbiAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgIDwhLS0gQ3VzdG9tIHNlcGFyYXRvciAoc2xhc2gpIC0tPlxuICAgICAgICA8c3ZnXG4gICAgICAgICAgKm5nSWY9XCJtb2RlID09PSAnY3VzdG9tLXNlcGFyYXRvcicgJiYgaXRlbSAhPT0gJy4uLidcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICAgIGNsYXNzPVwiaC00IHctNFwiXG4gICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICA+XG4gICAgICAgICAgPHBhdGggZD1cIk04IDIwTDE2IDRcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIxLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICAgIFxuICAgICAgICA8IS0tIERlZmF1bHQgc2VwYXJhdG9yIChjaGV2cm9uKSAtLT5cbiAgICAgICAgPHN2Z1xuICAgICAgICAgICpuZ0lmPVwiKG1vZGUgIT09ICdjdXN0b20tc2VwYXJhdG9yJyAmJiBpdGVtICE9PSAnLi4uJykgfHwgaXRlbSA9PT0gJy4uLidcIlxuICAgICAgICAgIHZpZXdCb3g9XCIwIDAgMjQgMjRcIlxuICAgICAgICAgIGNsYXNzPVwiaC00IHctNFwiXG4gICAgICAgICAgZmlsbD1cIm5vbmVcIlxuICAgICAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxuICAgICAgICA+XG4gICAgICAgICAgPHBhdGggZD1cIk05IDZMMTUgMTJMOSAxOFwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XG4gICAgICAgIDwvc3ZnPlxuICAgICAgPC9zcGFuPlxuICAgICAgXG4gICAgICA8IS0tIEVsbGlwc2lzIGluZGljYXRvciBmb3IgcmVzcG9uc2l2ZSBtb2RlIChvbmx5IHNob3duIHdoZW4gaXRlbXMgYXJlIGhpZGRlbikgLS0+XG4gICAgICA8c3BhbiBcbiAgICAgICAgKm5nSWY9XCJtb2RlID09PSAncmVzcG9uc2l2ZScgJiYgIXNob3VsZFNob3dJbk1vYmlsZShpKSAmJiBpID09PSAwXCJcbiAgICAgICAgY2xhc3M9XCJpbmxpbmUtZmxleCBzbTpoaWRkZW4gdGV4dC1tdXRlZC1mb3JlZ3JvdW5kXCI+XG4gICAgICAgIC4uLlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgPCEtLSBEcm9wZG93biBpbmRpY2F0b3IgLS0+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1vZGUgPT09ICdkcm9wZG93bicgJiYgaSA9PT0gMSAmJiBpdGVtICE9PSAnLi4uJyAmJiAhbGFzdFwiPlxuICAgICAgPHNwYW4gY2xhc3M9XCItbWwtMiBpbmxpbmUtZmxleCBoLTYgdy02IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciB0ZXh0LW11dGVkLWZvcmVncm91bmRcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgPHN2ZyB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgY2xhc3M9XCJoLTQgdy00XCIgZmlsbD1cIm5vbmVcIiB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCI+XG4gICAgICAgICAgPHBhdGggZD1cIk03IDEwTDEyIDE1TDE3IDEwXCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIgLz5cbiAgICAgICAgPC9zdmc+XG4gICAgICA8L3NwYW4+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uYXY+XG4iXX0=
|