tailjng 0.1.5 → 0.1.7
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 +12 -4
- package/cli/execute/init-app.js +5 -3
- package/cli/execute/sync-app.js +14 -2
- package/cli/settings/colors-config-utils.js +43 -8
- package/cli/settings/icons-config-utils.js +62 -0
- package/cli/settings/path-utils.js +32 -2
- package/cli/settings/project-utils.js +7 -1
- package/cli/templates/app.generator.js +2 -2
- package/fesm2022/tailjng.mjs +247 -80
- package/fesm2022/tailjng.mjs.map +1 -1
- package/lib/services/static/theme.service.d.ts +39 -1
- package/lib/utils/theme/theme-variables.util.d.ts +31 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -1
- package/registry/components.json +41 -18
- package/src/colors.safelist.css +2 -2
- package/src/lib/components/.config/README.md +11 -0
- package/src/lib/components/.config/colors/README.md +38 -0
- package/src/lib/components/{colors-config → .config/colors}/colors.config.ts +5 -5
- package/src/lib/components/{colors-config → .config/colors}/colors.safelist.css +2 -2
- package/src/lib/components/.config/icons/README.md +26 -0
- package/src/lib/components/.config/icons/icons.lucide.ts +134 -0
- package/src/lib/components/.config/input/README.md +24 -0
- package/src/lib/components/.config/input/input.classes.ts +119 -0
- package/src/lib/components/alert/alert-dialog/dialog-alert.component.css +244 -2
- package/src/lib/components/alert/alert-dialog/dialog-alert.component.html +25 -38
- package/src/lib/components/alert/alert-dialog/dialog-alert.component.ts +66 -56
- package/src/lib/components/alert/alert-dialog/dialog-alert.types.ts +19 -0
- package/src/lib/components/alert/alert-toast/toast-alert.component.css +630 -12
- package/src/lib/components/alert/alert-toast/toast-alert.component.html +103 -102
- package/src/lib/components/alert/alert-toast/toast-alert.component.ts +485 -128
- package/src/lib/components/alert/alert-toast/toast-alert.types.ts +25 -0
- package/src/lib/components/badge/badge.component.html +34 -21
- package/src/lib/components/badge/badge.component.ts +140 -31
- package/src/lib/components/button/button.component.html +16 -10
- package/src/lib/components/button/button.component.ts +162 -22
- package/src/lib/components/card/card-complete/complete-card.component.html +2 -2
- package/src/lib/components/card/card-complete/complete-card.component.ts +26 -16
- package/src/lib/components/card/card-crud-complete/complete-crud-card.component.html +2 -2
- package/src/lib/components/card/card-crud-complete/complete-crud-card.component.ts +26 -16
- package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.css +97 -0
- package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.html +54 -46
- package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.ts +135 -64
- package/src/lib/components/checkbox/checkbox-input/input-checkbox.types.ts +3 -0
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.css +112 -0
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.html +28 -25
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.ts +67 -15
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.types.ts +1 -0
- package/src/lib/components/coach-mark/coach-mark.component.html +4 -22
- package/src/lib/components/coach-mark/coach-mark.component.scss +1 -1
- package/src/lib/components/coach-mark/coach-mark.component.ts +51 -18
- package/src/lib/components/coach-mark/coach-mark.directive.ts +133 -78
- package/src/lib/components/coach-mark/coach-mark.types.ts +12 -0
- package/src/lib/components/dialog/dialog.component.css +103 -1
- package/src/lib/components/dialog/dialog.component.html +46 -66
- package/src/lib/components/dialog/dialog.component.ts +136 -110
- package/src/lib/components/dialog/dialog.types.ts +19 -0
- package/src/lib/components/filter/filter-complete/complete-filter.component.html +16 -19
- package/src/lib/components/filter/filter-complete/complete-filter.component.scss +35 -0
- package/src/lib/components/filter/filter-complete/complete-filter.component.ts +58 -34
- package/src/lib/components/filter/filter-complete/complete-filter.types.ts +7 -0
- package/src/lib/components/filter/filter-complete/complete-filter.util.ts +16 -0
- package/src/lib/components/form/form-container/container-form.component.css +4 -0
- package/src/lib/components/form/form-container/container-form.component.html +2 -2
- package/src/lib/components/form/form-container/container-form.component.ts +72 -16
- package/src/lib/components/form/form-container/container-form.types.ts +42 -0
- package/src/lib/components/form/form-container/form-col-span.directive.ts +25 -0
- package/src/lib/components/form/form-sidebar/sidebar-form.component.css +276 -0
- package/src/lib/components/form/form-sidebar/sidebar-form.component.html +117 -125
- package/src/lib/components/form/form-sidebar/sidebar-form.component.ts +109 -34
- package/src/lib/components/form/form-sidebar/sidebar-form.types.ts +3 -0
- package/src/lib/components/{toggle-radio/toggle-radio.component.css → form/form-validation/validation-form.component.css} +0 -1
- package/src/lib/components/form/form-validation/validation-form.component.html +10 -6
- package/src/lib/components/form/form-validation/validation-form.component.ts +99 -12
- package/src/lib/components/form/form-validation/validation-form.types.ts +33 -0
- package/src/lib/components/icon/icon.component.html +8 -5
- package/src/lib/components/icon/icon.component.ts +111 -9
- package/src/lib/components/input/input/input.component.html +19 -16
- package/src/lib/components/input/input/input.component.ts +130 -53
- package/src/lib/components/input/input/input.types.ts +8 -0
- package/src/lib/components/input/input-file/file-input.component.html +65 -56
- package/src/lib/components/input/input-file/file-input.component.ts +276 -173
- package/src/lib/components/input/input-file/file-input.types.ts +2 -0
- package/src/lib/components/input/input-range/range-input.component.css +67 -0
- package/src/lib/components/input/input-range/range-input.component.html +50 -58
- package/src/lib/components/input/input-range/range-input.component.ts +148 -60
- package/src/lib/components/input/input-range/range-input.types.ts +7 -0
- package/src/lib/components/input/input-textarea/textarea-input.component.html +16 -7
- package/src/lib/components/input/input-textarea/textarea-input.component.ts +140 -50
- package/src/lib/components/input/input-textarea/textarea-input.types.ts +2 -0
- package/src/lib/components/label/label.component.html +17 -16
- package/src/lib/components/label/label.component.ts +70 -16
- package/src/lib/components/label/label.types.ts +2 -0
- package/src/lib/components/menu/menu-options-table/menu-options-defaults.ts +34 -0
- package/src/lib/components/menu/menu-options-table/options-table-menu.component.html +34 -20
- package/src/lib/components/menu/menu-options-table/options-table-menu.component.ts +211 -58
- package/src/lib/components/menu/menu-options-table/options-table-menu.types.ts +38 -0
- package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.html +49 -52
- package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.ts +112 -24
- package/src/lib/components/menu/options-coach-menu/options-coach-menu.types.ts +9 -0
- package/src/lib/components/mode-toggle/mode-toggle.component.html +11 -16
- package/src/lib/components/mode-toggle/mode-toggle.component.ts +69 -33
- package/src/lib/components/paginator/paginator-complete/complete-paginator.component.html +4 -4
- package/src/lib/components/paginator/paginator-complete/complete-paginator.component.ts +31 -7
- package/src/lib/components/paginator/paginator-complete/complete-paginator.types.ts +12 -0
- package/src/lib/components/paginator/paginator-complete/complete-paginator.util.ts +36 -0
- package/src/lib/components/progress-bar/progress-bar.component.css +11 -0
- package/src/lib/components/progress-bar/progress-bar.component.html +41 -40
- package/src/lib/components/progress-bar/progress-bar.component.ts +95 -11
- package/src/lib/components/progress-bar/progress-bar.types.ts +2 -0
- package/src/lib/components/select/select-dropdown/dropdown-select.component.css +6 -0
- package/src/lib/components/select/select-dropdown/dropdown-select.component.html +54 -44
- package/src/lib/components/select/select-dropdown/dropdown-select.component.ts +450 -509
- package/src/lib/components/select/select-dropdown/dropdown-select.types.ts +43 -0
- package/src/lib/components/select/select-dropdown/dropdown-select.util.ts +179 -0
- package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.css +6 -0
- package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.html +131 -42
- package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.component.ts +491 -475
- package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.types.ts +22 -0
- package/src/lib/components/select/select-multi-dropdown/multi-dropdown-select.util.ts +20 -0
- package/src/lib/components/select/select-multi-table/multi-table-select.component.css +10 -0
- package/src/lib/components/select/select-multi-table/multi-table-select.component.html +76 -60
- package/src/lib/components/select/select-multi-table/multi-table-select.component.ts +250 -313
- package/src/lib/components/select/select-multi-table/multi-table-select.types.ts +10 -0
- package/src/lib/components/select/select-multi-table/multi-table-select.util.ts +5 -0
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.css +212 -0
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.html +62 -53
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.ts +84 -27
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.types.ts +2 -0
- package/src/lib/components/table/table-complete/complete-table.component.html +15 -17
- package/src/lib/components/table/table-complete/complete-table.component.ts +190 -338
- package/src/lib/components/table/table-complete/complete-table.types.ts +28 -0
- package/src/lib/components/table/table-complete/complete-table.util.ts +236 -0
- package/src/lib/components/table/table-complete/index.ts +2 -0
- package/src/lib/components/table/table-crud-complete/complete-crud-table.animations.ts +34 -0
- package/src/lib/components/table/table-crud-complete/complete-crud-table.component.html +73 -128
- package/src/lib/components/table/table-crud-complete/complete-crud-table.component.ts +542 -829
- package/src/lib/components/table/table-crud-complete/complete-crud-table.types.ts +57 -0
- package/src/lib/components/table/table-crud-complete/complete-crud-table.util.ts +723 -0
- package/src/lib/components/table/table-crud-complete/index.ts +3 -0
- package/src/lib/components/theme-generator/theme-generator.component.css +21 -0
- package/src/lib/components/theme-generator/theme-generator.component.html +146 -116
- package/src/lib/components/theme-generator/theme-generator.component.ts +44 -24
- package/src/lib/components/toggle-radio/shared/toggle-options.types.ts +8 -0
- package/src/lib/components/toggle-radio/shared/toggle-options.util.ts +44 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.css +135 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.html +52 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.ts +198 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.types.ts +1 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.css +108 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.html +37 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.ts +193 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.types.ts +1 -0
- package/src/lib/components/tooltip/tooltip.directive.ts +12 -9
- package/src/lib/components/tooltip/tooltip.service.ts +331 -133
- package/src/lib/components/tooltip/tooltip.types.ts +9 -0
- package/src/lib/components/viewer/viewer-image/image-viewer.component.css +90 -4
- package/src/lib/components/viewer/viewer-image/image-viewer.component.html +52 -103
- package/src/lib/components/viewer/viewer-image/image-viewer.component.ts +182 -177
- package/src/lib/components/viewer/viewer-image/image-viewer.types.ts +3 -0
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.css +177 -0
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.html +74 -24
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.ts +168 -15
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.types.ts +1 -0
- package/src/styles.css +2 -2
- package/lib/services/static/icons.service.d.ts +0 -65
- package/src/lib/components/colors-config/README.md +0 -38
- package/src/lib/components/form/form-sidebar/sidebar-form.component.scss +0 -0
- package/src/lib/components/form/form-validation/validation-form.component.scss +0 -0
- package/src/lib/components/menu/menu-options-table/options-table-menu.component.scss +0 -0
- package/src/lib/components/menu/options-coach-menu/options-coach-menu.component.scss +0 -12
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.scss +0 -0
- package/src/lib/components/toggle-radio/toggle-radio.component.html +0 -51
- package/src/lib/components/toggle-radio/toggle-radio.component.ts +0 -222
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.scss +0 -0
- package/tailjng-0.1.5.tgz +0 -0
|
@@ -1,28 +1,78 @@
|
|
|
1
|
-
<div class="
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<div class="j-pdf-viewer" [ngClass]="ngClasses">
|
|
2
|
+
@if (!hasUrl) {
|
|
3
|
+
<div class="j-pdf-viewer__empty">
|
|
4
|
+
<JIcon
|
|
5
|
+
[icon]="Icons.CircleAlert"
|
|
6
|
+
[size]="32"
|
|
7
|
+
iconClass="text-muted-foreground"
|
|
8
|
+
[ariaHidden]="true"
|
|
9
|
+
/>
|
|
10
|
+
<p class="j-pdf-viewer__message">{{ emptyMessage }}</p>
|
|
11
|
+
</div>
|
|
12
|
+
} @else if (showDesktopEmbed) {
|
|
13
|
+
<iframe
|
|
14
|
+
class="j-pdf-viewer__frame"
|
|
15
|
+
[src]="safeUrl"
|
|
16
|
+
[title]="documentTitle"
|
|
17
|
+
loading="lazy"
|
|
18
|
+
></iframe>
|
|
19
|
+
} @else if (useMobileLayout) {
|
|
20
|
+
<div class="j-pdf-viewer__mobile">
|
|
21
|
+
@if (showMobileActions) {
|
|
22
|
+
<div class="j-pdf-viewer__mobile-card">
|
|
23
|
+
<JIcon
|
|
24
|
+
[icon]="Icons.FileUp"
|
|
25
|
+
[size]="36"
|
|
26
|
+
iconClass="text-primary dark:text-dark-primary"
|
|
27
|
+
[ariaHidden]="true"
|
|
28
|
+
/>
|
|
29
|
+
<div class="j-pdf-viewer__mobile-copy">
|
|
30
|
+
<h3 class="j-pdf-viewer__mobile-title">{{ documentTitle }}</h3>
|
|
31
|
+
<p class="j-pdf-viewer__mobile-text">
|
|
32
|
+
En móvil, abre el PDF en el visor del sistema para navegar y hacer zoom con
|
|
33
|
+
mejor experiencia.
|
|
34
|
+
</p>
|
|
35
|
+
</div>
|
|
36
|
+
<div class="j-pdf-viewer__actions j-pdf-viewer__actions--stacked">
|
|
37
|
+
<JButton
|
|
38
|
+
[text]="'Abrir PDF'"
|
|
39
|
+
[icon]="Icons.Eye"
|
|
40
|
+
(clicked)="openInBrowser()"
|
|
41
|
+
/>
|
|
42
|
+
<JButton
|
|
43
|
+
[text]="'Descargar'"
|
|
44
|
+
[icon]="Icons.Download"
|
|
45
|
+
classes="secondary"
|
|
46
|
+
(clicked)="downloadPdf()"
|
|
47
|
+
/>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
}
|
|
10
51
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
Puedes descargarlo y verlo en tu visor de PDF preferido.
|
|
19
|
-
</p>
|
|
20
|
-
</div>
|
|
52
|
+
@if (showMobileEmbed) {
|
|
53
|
+
<iframe
|
|
54
|
+
class="j-pdf-viewer__frame j-pdf-viewer__frame--mobile"
|
|
55
|
+
[src]="safeUrl"
|
|
56
|
+
[title]="documentTitle"
|
|
57
|
+
loading="lazy"
|
|
58
|
+
></iframe>
|
|
21
59
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
60
|
+
<div class="j-pdf-viewer__mobile-bar">
|
|
61
|
+
<JButton
|
|
62
|
+
[text]="'Abrir'"
|
|
63
|
+
[icon]="Icons.Eye"
|
|
64
|
+
size="sm"
|
|
65
|
+
(clicked)="openInBrowser()"
|
|
66
|
+
/>
|
|
67
|
+
<JButton
|
|
68
|
+
[text]="'Descargar'"
|
|
69
|
+
[icon]="Icons.Download"
|
|
70
|
+
size="sm"
|
|
71
|
+
classes="secondary"
|
|
72
|
+
(clicked)="downloadPdf()"
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
}
|
|
26
76
|
</div>
|
|
27
|
-
|
|
77
|
+
}
|
|
28
78
|
</div>
|
|
@@ -1,31 +1,184 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NgClass } from '@angular/common';
|
|
2
|
+
import {
|
|
3
|
+
Component,
|
|
4
|
+
HostListener,
|
|
5
|
+
Input,
|
|
6
|
+
OnChanges,
|
|
7
|
+
OnInit,
|
|
8
|
+
SimpleChanges,
|
|
9
|
+
} from '@angular/core';
|
|
2
10
|
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
11
|
+
import { Icons } from '../../.config/icons/icons.lucide';
|
|
12
|
+
import { JButtonComponent } from '../../button/button.component';
|
|
13
|
+
import { JIconComponent } from '../../icon/icon.component';
|
|
14
|
+
import { PdfViewerMobileMode } from './pdf-viewer.types';
|
|
5
15
|
|
|
16
|
+
export type { PdfViewerMobileMode } from './pdf-viewer.types';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* PDF viewer with desktop embed and a mobile-friendly open/download experience.
|
|
20
|
+
*
|
|
21
|
+
* Install: `npx tailjng add viewer-pdf`
|
|
22
|
+
*/
|
|
6
23
|
@Component({
|
|
7
24
|
selector: 'JPdfViewer',
|
|
8
|
-
|
|
9
|
-
imports: [LucideAngularModule],
|
|
25
|
+
imports: [NgClass, JButtonComponent, JIconComponent],
|
|
10
26
|
templateUrl: './pdf-viewer.component.html',
|
|
11
|
-
|
|
27
|
+
styleUrl: './pdf-viewer.component.css',
|
|
12
28
|
})
|
|
13
|
-
export class JPdfViewerComponent implements OnChanges {
|
|
29
|
+
export class JPdfViewerComponent implements OnInit, OnChanges {
|
|
30
|
+
readonly Icons = Icons;
|
|
14
31
|
|
|
15
|
-
|
|
16
|
-
@Input()
|
|
32
|
+
@Input() url = '';
|
|
33
|
+
@Input() title = '';
|
|
34
|
+
@Input() emptyMessage = 'No hay un PDF para mostrar';
|
|
35
|
+
@Input() mobileMode: PdfViewerMobileMode = 'auto';
|
|
36
|
+
/** When true on mobile (non-iOS), tries an iframe embed before falling back to actions only. */
|
|
37
|
+
@Input() mobileEmbed = true;
|
|
38
|
+
@Input() ngClasses: Record<string, boolean> = {};
|
|
17
39
|
|
|
18
|
-
// URLs “seguras” para <object>
|
|
19
40
|
safeUrl: SafeResourceUrl | null = null;
|
|
41
|
+
isMobileViewport = false;
|
|
42
|
+
|
|
43
|
+
constructor(private readonly sanitizer: DomSanitizer) {}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether the mobile layout should be used.
|
|
47
|
+
*/
|
|
48
|
+
get useMobileLayout(): boolean {
|
|
49
|
+
if (this.mobileMode === 'embed') {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (this.mobileMode === 'actions') {
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return this.isMobileViewport;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* iOS does not reliably render PDFs inside iframe/object.
|
|
62
|
+
*/
|
|
63
|
+
get isIOS(): boolean {
|
|
64
|
+
if (typeof navigator === 'undefined') {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
/iPad|iPhone|iPod/.test(navigator.userAgent) ||
|
|
70
|
+
(navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1)
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Whether to render the iframe on mobile (typically Android).
|
|
76
|
+
*/
|
|
77
|
+
get showMobileEmbed(): boolean {
|
|
78
|
+
return this.useMobileLayout && this.mobileEmbed && !this.isIOS && !!this.safeUrl;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Whether to show the mobile action card (open / download).
|
|
83
|
+
*/
|
|
84
|
+
get showMobileActions(): boolean {
|
|
85
|
+
return this.useMobileLayout && (!this.showMobileEmbed || this.isIOS);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Whether desktop embed mode is active.
|
|
90
|
+
*/
|
|
91
|
+
get showDesktopEmbed(): boolean {
|
|
92
|
+
return !this.useMobileLayout && !!this.safeUrl;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Display name derived from the URL or `title` input.
|
|
97
|
+
*/
|
|
98
|
+
get documentTitle(): string {
|
|
99
|
+
if (this.title.trim()) {
|
|
100
|
+
return this.title.trim();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!this.url) {
|
|
104
|
+
return 'Documento PDF';
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
const path = new URL(this.url, window.location.origin).pathname;
|
|
109
|
+
const fileName = path.split('/').pop();
|
|
110
|
+
return fileName ? decodeURIComponent(fileName) : 'Documento PDF';
|
|
111
|
+
} catch {
|
|
112
|
+
return 'Documento PDF';
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Whether a PDF URL is available.
|
|
118
|
+
*/
|
|
119
|
+
get hasUrl(): boolean {
|
|
120
|
+
return !!this.url?.trim();
|
|
121
|
+
}
|
|
20
122
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
) { }
|
|
123
|
+
ngOnInit(): void {
|
|
124
|
+
this.syncViewport();
|
|
125
|
+
}
|
|
25
126
|
|
|
26
127
|
ngOnChanges(changes: SimpleChanges): void {
|
|
27
128
|
if (changes['url']) {
|
|
28
|
-
this.safeUrl = this.
|
|
129
|
+
this.safeUrl = this.hasUrl
|
|
130
|
+
? this.sanitizer.bypassSecurityTrustResourceUrl(this.buildEmbedUrl(this.url))
|
|
131
|
+
: null;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
@HostListener('window:resize')
|
|
136
|
+
onWindowResize(): void {
|
|
137
|
+
this.syncViewport();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Opens the PDF in a new browser tab (native viewer on mobile).
|
|
142
|
+
*/
|
|
143
|
+
openInBrowser(): void {
|
|
144
|
+
if (!this.hasUrl) {
|
|
145
|
+
return;
|
|
29
146
|
}
|
|
147
|
+
|
|
148
|
+
window.open(this.url, '_blank', 'noopener,noreferrer');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Triggers download / open for the PDF file.
|
|
153
|
+
*/
|
|
154
|
+
downloadPdf(): void {
|
|
155
|
+
if (!this.hasUrl) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const link = document.createElement('a');
|
|
160
|
+
link.href = this.url;
|
|
161
|
+
link.target = '_blank';
|
|
162
|
+
link.rel = 'noopener noreferrer';
|
|
163
|
+
link.download = this.documentTitle;
|
|
164
|
+
document.body.appendChild(link);
|
|
165
|
+
link.click();
|
|
166
|
+
document.body.removeChild(link);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
private syncViewport(): void {
|
|
170
|
+
if (typeof window === 'undefined') {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
this.isMobileViewport = window.matchMedia('(max-width: 767px)').matches;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private buildEmbedUrl(rawUrl: string): string {
|
|
178
|
+
if (rawUrl.includes('#')) {
|
|
179
|
+
return rawUrl;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return `${rawUrl}#view=FitH`;
|
|
30
183
|
}
|
|
31
184
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type PdfViewerMobileMode = 'auto' | 'embed' | 'actions';
|
package/src/styles.css
CHANGED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import * as i0 from "@angular/core";
|
|
2
|
-
export declare class JIconsService {
|
|
3
|
-
icons: {
|
|
4
|
-
info: import("lucide-angular").LucideIconData;
|
|
5
|
-
success: import("lucide-angular").LucideIconData;
|
|
6
|
-
error: import("lucide-angular").LucideIconData;
|
|
7
|
-
warning: import("lucide-angular").LucideIconData;
|
|
8
|
-
question: import("lucide-angular").LucideIconData;
|
|
9
|
-
close: import("lucide-angular").LucideIconData;
|
|
10
|
-
check: import("lucide-angular").LucideIconData;
|
|
11
|
-
zoomIn: import("lucide-angular").LucideIconData;
|
|
12
|
-
zoomOut: import("lucide-angular").LucideIconData;
|
|
13
|
-
rotateRight: import("lucide-angular").LucideIconData;
|
|
14
|
-
rotateLeft: import("lucide-angular").LucideIconData;
|
|
15
|
-
reset: import("lucide-angular").LucideIconData;
|
|
16
|
-
fullscreen: import("lucide-angular").LucideIconData;
|
|
17
|
-
exitFullscreen: import("lucide-angular").LucideIconData;
|
|
18
|
-
img: import("lucide-angular").LucideIconData;
|
|
19
|
-
imgs: import("lucide-angular").LucideIconData;
|
|
20
|
-
imageOff: import("lucide-angular").LucideIconData;
|
|
21
|
-
upload: import("lucide-angular").LucideIconData;
|
|
22
|
-
view: import("lucide-angular").LucideIconData;
|
|
23
|
-
chevronUp: import("lucide-angular").LucideIconData;
|
|
24
|
-
chevronDown: import("lucide-angular").LucideIconData;
|
|
25
|
-
chevronsUpDown: import("lucide-angular").LucideIconData;
|
|
26
|
-
squareDashedMousePointer: import("lucide-angular").LucideIconData;
|
|
27
|
-
search: import("lucide-angular").LucideIconData;
|
|
28
|
-
copy: import("lucide-angular").LucideIconData;
|
|
29
|
-
save: import("lucide-angular").LucideIconData;
|
|
30
|
-
sun: import("lucide-angular").LucideIconData;
|
|
31
|
-
moon: import("lucide-angular").LucideIconData;
|
|
32
|
-
loading: import("lucide-angular").LucideIconData;
|
|
33
|
-
table: import("lucide-angular").LucideIconData;
|
|
34
|
-
listFilter: import("lucide-angular").LucideIconData;
|
|
35
|
-
firstPage: import("lucide-angular").LucideIconData;
|
|
36
|
-
prevPage: import("lucide-angular").LucideIconData;
|
|
37
|
-
nextPage: import("lucide-angular").LucideIconData;
|
|
38
|
-
lastPage: import("lucide-angular").LucideIconData;
|
|
39
|
-
arrowBigRight: import("lucide-angular").LucideIconData;
|
|
40
|
-
filter: import("lucide-angular").LucideIconData;
|
|
41
|
-
filterList: import("lucide-angular").LucideIconData;
|
|
42
|
-
eraser: import("lucide-angular").LucideIconData;
|
|
43
|
-
transh: import("lucide-angular").LucideIconData;
|
|
44
|
-
default: import("lucide-angular").LucideIconData;
|
|
45
|
-
fileSpreadsheet: import("lucide-angular").LucideIconData;
|
|
46
|
-
monitorUp: import("lucide-angular").LucideIconData;
|
|
47
|
-
download: import("lucide-angular").LucideIconData;
|
|
48
|
-
fileUp: import("lucide-angular").LucideIconData;
|
|
49
|
-
listRestart: import("lucide-angular").LucideIconData;
|
|
50
|
-
editRowLine: import("lucide-angular").LucideIconData;
|
|
51
|
-
editRow: import("lucide-angular").LucideIconData;
|
|
52
|
-
edit: import("lucide-angular").LucideIconData;
|
|
53
|
-
delete: import("lucide-angular").LucideIconData;
|
|
54
|
-
ellipsisVertical: import("lucide-angular").LucideIconData;
|
|
55
|
-
calendar: import("lucide-angular").LucideIconData;
|
|
56
|
-
clock: import("lucide-angular").LucideIconData;
|
|
57
|
-
circleAlert: import("lucide-angular").LucideIconData;
|
|
58
|
-
clipboard: import("lucide-angular").LucideIconData;
|
|
59
|
-
link: import("lucide-angular").LucideIconData;
|
|
60
|
-
linkOff: import("lucide-angular").LucideIconData;
|
|
61
|
-
};
|
|
62
|
-
constructor();
|
|
63
|
-
static ɵfac: i0.ɵɵFactoryDeclaration<JIconsService, never>;
|
|
64
|
-
static ɵprov: i0.ɵɵInjectableDeclaration<JIconsService>;
|
|
65
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
# Colores Tailjng — configuración del proyecto
|
|
2
|
-
|
|
3
|
-
Carpeta generada por `init:app`, `sync:app` o `npx tailjng add colors`.
|
|
4
|
-
|
|
5
|
-
## Archivos
|
|
6
|
-
|
|
7
|
-
| Archivo | Para qué |
|
|
8
|
-
|---------|----------|
|
|
9
|
-
| `colors.config.ts` | Variantes (`primary`, `success_soft`, …) + las tuyas (`brand`, etc.) |
|
|
10
|
-
| `colors.safelist.css` | Clases Tailwind que el build debe generar (`@apply`) |
|
|
11
|
-
|
|
12
|
-
## Añadir un color propio
|
|
13
|
-
|
|
14
|
-
**1.** En `colors.config.ts`:
|
|
15
|
-
|
|
16
|
-
```typescript
|
|
17
|
-
brand: 'bg-indigo-600 text-white hover:bg-indigo-700 border border-indigo-500 shadow-md',
|
|
18
|
-
brand_soft: 'bg-indigo-500/10 text-indigo-600 border border-indigo-500/20 shadow-sm',
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
**2.** En `colors.safelist.css`, dentro del bloque `@layer utilities`:
|
|
22
|
-
|
|
23
|
-
```css
|
|
24
|
-
.__tailjng_custom_colors__ {
|
|
25
|
-
@apply bg-indigo-600 text-white hover:bg-indigo-700 border-indigo-500 bg-indigo-500/10 text-indigo-600;
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**3.** Uso en componentes:
|
|
30
|
-
|
|
31
|
-
```html
|
|
32
|
-
<JButton classes="brand" text="Guardar" />
|
|
33
|
-
<JBadge classes="brand_soft" value="N" />
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Provider
|
|
37
|
-
|
|
38
|
-
`app.config.ts` debe incluir `tailjngColorsProvider` (lo añade `init:app` / `sync:app`).
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
@if (internalOptions.length > 0) {
|
|
2
|
-
<div class="flex rounded-md overflow-hidden border border-border dark:border-dark-border text-sm min-h-[40px] select-none" [ngClass]="{ 'opacity-50': isDisabled || isComponentDisabled }" [class]="classes">
|
|
3
|
-
|
|
4
|
-
<ng-container>
|
|
5
|
-
@for (opt of internalOptions; track $index) {
|
|
6
|
-
<button
|
|
7
|
-
type="button"
|
|
8
|
-
[disabled]="isDisabled || isComponentDisabled"
|
|
9
|
-
(click)="select(opt.value)"
|
|
10
|
-
[ngClass]="{
|
|
11
|
-
'bg-primary dark:bg-dark-primary text-white': selectedValue === opt.value,
|
|
12
|
-
'bg-background dark:bg-dark-background hover:bg-muted/80 hover:dark:bg-dark-muted/30 text-gray-700 dark:text-white': selectedValue !== opt.value,
|
|
13
|
-
'cursor-not-allowed pointer-events-none': isDisabled || isComponentDisabled
|
|
14
|
-
}"
|
|
15
|
-
class="w-full py-2 px-4 font-medium border-r border-border last:border-none focus:outline-none transition-colors duration-200 ease-in-out cursor-pointer"
|
|
16
|
-
[class]="classesElement"
|
|
17
|
-
>
|
|
18
|
-
{{ opt.label }}
|
|
19
|
-
</button>
|
|
20
|
-
}
|
|
21
|
-
</ng-container>
|
|
22
|
-
|
|
23
|
-
</div>
|
|
24
|
-
} @else if (isLoading) {
|
|
25
|
-
|
|
26
|
-
<div class="flex text-black dark:text-white gap-2 items-center justify-center rounded-md overflow-hidden border border-border dark:border-dark-border h-[40px]">
|
|
27
|
-
<lucide-icon [name]="iconsService.icons.loading" [size]="15" class="text-gray-400 animate-spin" />
|
|
28
|
-
<span>Cargando...</span>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
} @else {
|
|
32
|
-
|
|
33
|
-
<div class="flex text-black dark:text-white items-center justify-center rounded-md overflow-hidden border border-border dark:border-dark-border h-[40px]">
|
|
34
|
-
No hay opciones
|
|
35
|
-
</div>
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
<!-- Clear button -->
|
|
40
|
-
@if (showClear && selectedValue !== null) {
|
|
41
|
-
<div class="mt-2">
|
|
42
|
-
<button
|
|
43
|
-
type="button"
|
|
44
|
-
(click)="clear()"
|
|
45
|
-
[disabled]="isDisabled || isComponentDisabled"
|
|
46
|
-
class="text-xs text-red-500 underline disabled:opacity-50 disabled:cursor-not-allowed">
|
|
47
|
-
Limpiar selección
|
|
48
|
-
</button>
|
|
49
|
-
</div>
|
|
50
|
-
}
|
|
51
|
-
|