tailjng 0.1.6 → 0.1.8
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 +27 -5
- package/cli/execute/init-app.js +5 -2
- package/cli/execute/sync-app.js +14 -2
- package/cli/settings/colors-config-utils.js +69 -11
- 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 +8 -5
- 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 +40 -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 +177 -6
- package/src/lib/components/alert/alert-dialog/dialog-alert.component.html +24 -37
- 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 +494 -14
- package/src/lib/components/alert/alert-toast/toast-alert.component.html +106 -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 +30 -0
- package/src/lib/components/checkbox/checkbox-input/input-checkbox.component.html +58 -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 +62 -0
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.html +39 -25
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.component.ts +74 -15
- package/src/lib/components/checkbox/checkbox-switch/switch-checkbox.types.ts +1 -0
- package/src/lib/components/coach-mark/coach-mark.component.html +6 -24
- package/src/lib/components/coach-mark/coach-mark.component.scss +1 -7
- 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 +1 -1
- package/src/lib/components/dialog/dialog.component.html +56 -65
- 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 +17 -20
- package/src/lib/components/filter/filter-complete/complete-filter.component.scss +25 -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 +45 -0
- package/src/lib/components/form/form-sidebar/sidebar-form.component.html +128 -124
- package/src/lib/components/form/form-sidebar/sidebar-form.component.ts +114 -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.css +0 -14
- 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 +94 -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.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.html +56 -46
- 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.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 +4 -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 +155 -0
- package/src/lib/components/sidebar/sidebar-static/static-sidebar.component.html +72 -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 +21 -23
- 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 +87 -142
- package/src/lib/components/table/table-crud-complete/complete-crud-table.component.scss +0 -63
- package/src/lib/components/table/table-crud-complete/complete-crud-table.component.ts +544 -831
- 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 +141 -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 +62 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.css +22 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.html +65 -0
- package/src/lib/components/toggle-radio/toggle-radio/toggle-radio.component.ts +192 -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 +34 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.html +47 -0
- package/src/lib/components/toggle-radio/toggle-segment/segment-toggle.component.ts +187 -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 +14 -4
- package/src/lib/components/viewer/viewer-image/image-viewer.component.html +61 -95
- 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 +25 -0
- package/src/lib/components/viewer/viewer-pdf/pdf-viewer.component.html +95 -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.6.tgz +0 -0
|
@@ -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
|
-
|
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
import { CommonModule } from '@angular/common';
|
|
2
|
-
import { Component, EventEmitter, forwardRef, Input, OnChanges, OnInit, Optional, Output, SimpleChanges } from '@angular/core';
|
|
3
|
-
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
4
|
-
import { LucideAngularModule } from 'lucide-angular';
|
|
5
|
-
import { JIconsService, JGenericCrudService } from 'tailjng';
|
|
6
|
-
|
|
7
|
-
@Component({
|
|
8
|
-
selector: 'JToggleRadio',
|
|
9
|
-
imports: [LucideAngularModule, CommonModule],
|
|
10
|
-
templateUrl: './toggle-radio.component.html',
|
|
11
|
-
styleUrl: './toggle-radio.component.css',
|
|
12
|
-
providers: [
|
|
13
|
-
{
|
|
14
|
-
provide: NG_VALUE_ACCESSOR,
|
|
15
|
-
useExisting: forwardRef(() => JToggleRadioComponent),
|
|
16
|
-
multi: true,
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
})
|
|
20
|
-
export class JToggleRadioComponent implements OnInit, OnChanges, ControlValueAccessor {
|
|
21
|
-
|
|
22
|
-
@Input() endpoint: string = '';
|
|
23
|
-
|
|
24
|
-
@Input() options: any[] = [];
|
|
25
|
-
@Input() optionLabel = 'label';
|
|
26
|
-
@Input() optionValue = 'value';
|
|
27
|
-
|
|
28
|
-
@Input() sort: 'ASC' | 'DESC' = 'ASC';
|
|
29
|
-
@Input() defaultFilters: { [key: string]: any } = {};
|
|
30
|
-
|
|
31
|
-
@Input() loadOnInit = false;
|
|
32
|
-
@Input() selectFirstOnLoad: boolean = false;
|
|
33
|
-
|
|
34
|
-
@Input() isDisabled: boolean = false;
|
|
35
|
-
@Input() showClear = false;
|
|
36
|
-
|
|
37
|
-
@Input() classes: string = '';
|
|
38
|
-
@Input() classesElement: string = '';
|
|
39
|
-
|
|
40
|
-
@Output() selectionChange = new EventEmitter<any>();
|
|
41
|
-
|
|
42
|
-
internalOptions: { value: any; label: string }[] = [];
|
|
43
|
-
selectedValue: any = null;
|
|
44
|
-
isLoading = false;
|
|
45
|
-
|
|
46
|
-
isComponentDisabled = false;
|
|
47
|
-
|
|
48
|
-
// ControlValueAccessor
|
|
49
|
-
onChange: any = () => { };
|
|
50
|
-
onTouched: any = () => { };
|
|
51
|
-
|
|
52
|
-
constructor(
|
|
53
|
-
public readonly iconsService: JIconsService,
|
|
54
|
-
@Optional() private readonly genericService: JGenericCrudService | null,
|
|
55
|
-
) { }
|
|
56
|
-
|
|
57
|
-
ngOnInit(): void {
|
|
58
|
-
if (this.endpoint && this.loadOnInit) {
|
|
59
|
-
this.loadOptionsFromApi();
|
|
60
|
-
} else {
|
|
61
|
-
this.processOptions();
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
ngOnChanges(changes: SimpleChanges): void {
|
|
66
|
-
if (changes['options'] && !this.endpoint) {
|
|
67
|
-
this.processOptions();
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Set the disabled state of the component.
|
|
75
|
-
* This method is part of the ControlValueAccessor interface.
|
|
76
|
-
* @param isDisabled
|
|
77
|
-
*/
|
|
78
|
-
setDisabledState(isDisabled: boolean): void {
|
|
79
|
-
this.isComponentDisabled = isDisabled;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Load options from the API based on the endpoint and default filters.
|
|
86
|
-
* This method fetches data from the API and processes it to set the internal options.
|
|
87
|
-
*/
|
|
88
|
-
loadOptionsFromApi() {
|
|
89
|
-
if (!this.genericService || !this.endpoint) return;
|
|
90
|
-
|
|
91
|
-
this.isLoading = true;
|
|
92
|
-
|
|
93
|
-
const params: any = {};
|
|
94
|
-
params['sortOrder'] = this.sort;
|
|
95
|
-
|
|
96
|
-
Object.keys(this.defaultFilters).forEach((key) => {
|
|
97
|
-
params[`filter[${key}]`] = this.defaultFilters[key];
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
this.genericService.findAll<any>({ endpoint: this.endpoint, params }).subscribe({
|
|
101
|
-
next: (res) => {
|
|
102
|
-
const data = res.data[this.endpoint] || [];
|
|
103
|
-
this.options = data;
|
|
104
|
-
this.processOptions();
|
|
105
|
-
this.isLoading = false;
|
|
106
|
-
|
|
107
|
-
// If selectFirstOnLoad is true, select the first element
|
|
108
|
-
if (this.selectFirstOnLoad && this.internalOptions.length > 0) {
|
|
109
|
-
this.selectedValue = this.internalOptions[0].value;
|
|
110
|
-
this.onChange(this.selectedValue);
|
|
111
|
-
this.selectionChange.emit(this.selectedValue);
|
|
112
|
-
}
|
|
113
|
-
},
|
|
114
|
-
error: () => (this.isLoading = false),
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Get a nested value from an object using a dot-separated path.
|
|
122
|
-
* @param obj The object to search.
|
|
123
|
-
* @param path The dot-separated path to the desired value.
|
|
124
|
-
* @returns The value found at the specified path, or an empty string if not found.
|
|
125
|
-
*/
|
|
126
|
-
getNestedValue(obj: any, path: string): any {
|
|
127
|
-
return path.split('.').reduce((acc, part) => acc && acc[part], obj) ?? '';
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Process the options to extract value and label.
|
|
134
|
-
* This method checks if the options are objects and extracts the specified value and label.
|
|
135
|
-
*/
|
|
136
|
-
processOptions() {
|
|
137
|
-
if (this.options.length > 0 && typeof this.options[0] === 'object') {
|
|
138
|
-
|
|
139
|
-
this.internalOptions = this.options.map((opt) => ({
|
|
140
|
-
value: opt[this.optionValue],
|
|
141
|
-
label: this.getNestedValue(opt, this.optionLabel),
|
|
142
|
-
}));
|
|
143
|
-
|
|
144
|
-
} else {
|
|
145
|
-
this.internalOptions = this.options.map((opt) => ({
|
|
146
|
-
value: opt,
|
|
147
|
-
label: opt.toString(),
|
|
148
|
-
}));
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Select an option.
|
|
156
|
-
* @param value The value of the option to select.
|
|
157
|
-
* @returns
|
|
158
|
-
*/
|
|
159
|
-
select(value: any) {
|
|
160
|
-
if (this.isDisabled || this.isComponentDisabled) return;
|
|
161
|
-
this.selectedValue = value;
|
|
162
|
-
this.onChange(this.selectedValue);
|
|
163
|
-
this.selectionChange.emit(this.selectedValue);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Clear the selected value.
|
|
170
|
-
*/
|
|
171
|
-
clear() {
|
|
172
|
-
this.selectedValue = null;
|
|
173
|
-
this.onChange(null);
|
|
174
|
-
this.selectionChange.emit(null);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* Write the value to the component.
|
|
181
|
-
* This method is part of the ControlValueAccessor interface.
|
|
182
|
-
* It updates the selected value and notifies the change.
|
|
183
|
-
* @param value The value to write.
|
|
184
|
-
*/
|
|
185
|
-
writeValue(value: any): void {
|
|
186
|
-
this.selectedValue = value;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* Register a callback function to be called when the value changes.
|
|
193
|
-
* This method is part of the ControlValueAccessor interface.
|
|
194
|
-
* @param fn
|
|
195
|
-
*/
|
|
196
|
-
registerOnChange(fn: any): void {
|
|
197
|
-
this.onChange = fn;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Register a callback function to be called when the control is touched.
|
|
204
|
-
* This method is part of the ControlValueAccessor interface.
|
|
205
|
-
* @param fn The callback function to register.
|
|
206
|
-
*/
|
|
207
|
-
registerOnTouched(fn: any): void {
|
|
208
|
-
this.onTouched = fn;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Reload the options based on the current filters.
|
|
215
|
-
* This method can be called to refresh the options displayed in the toggle radio component.
|
|
216
|
-
*/
|
|
217
|
-
reloadOptions() {
|
|
218
|
-
if (!this.genericService) return;
|
|
219
|
-
this.loadOptionsFromApi();
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
}
|
|
File without changes
|
package/tailjng-0.1.6.tgz
DELETED
|
Binary file
|